﻿#include "ServerPackets.h"

namespace ServerPackets
{

    short KeepAlive::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::KeepAlive);
    }

    void KeepAlive::ReadPacket(BinaryReader *reader)
    {
        Time = reader->ReadInt64();
    }

    void KeepAlive::WritePacket(BinaryWriter *writer)
    {
        writer->Write(Time);
    }

    short Connected::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::Connected);
    }

    void Connected::ReadPacket(BinaryReader *reader)
    {
    }

    void Connected::WritePacket(BinaryWriter *writer)
    {
    }

    short ClientVersion::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::ClientVersion);
    }

    void ClientVersion::ReadPacket(BinaryReader *reader)
    {
        Result = reader->ReadByte();
    }

    void ClientVersion::WritePacket(BinaryWriter *writer)
    {
        writer->Write(Result);
    }

    short Disconnect::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::Disconnect);
    }

    void Disconnect::ReadPacket(BinaryReader *reader)
    {
        Reason = reader->ReadByte();
    }

    void Disconnect::WritePacket(BinaryWriter *writer)
    {
        writer->Write(Reason);
    }

    short NewAccount::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::NewAccount);
    }

    void NewAccount::ReadPacket(BinaryReader *reader)
    {
        Result = reader->ReadByte();
    }

    void NewAccount::WritePacket(BinaryWriter *writer)
    {
        writer->Write(Result);
    }

    short ChangePassword::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::ChangePassword);
    }

    void ChangePassword::ReadPacket(BinaryReader *reader)
    {
        Result = reader->ReadByte();
    }

    void ChangePassword::WritePacket(BinaryWriter *writer)
    {
        writer->Write(Result);
    }

    short ChangePasswordBanned::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::ChangePasswordBanned);
    }

    void ChangePasswordBanned::ReadPacket(BinaryReader *reader)
    {
        Reason = reader->ReadString();
        ExpiryDate = DateTime::FromBinary(reader->ReadInt64());
    }

    void ChangePasswordBanned::WritePacket(BinaryWriter *writer)
    {
        writer->Write(Reason);
        writer->Write(ExpiryDate.ToBinary());
    }

    short Login::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::Login);
    }

    void Login::ReadPacket(BinaryReader *reader)
    {
        Result = reader->ReadByte();
    }

    void Login::WritePacket(BinaryWriter *writer)
    {
        writer->Write(Result);
    }

    short LoginBanned::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::LoginBanned);
    }

    void LoginBanned::ReadPacket(BinaryReader *reader)
    {
        Reason = reader->ReadString();
        ExpiryDate = DateTime::FromBinary(reader->ReadInt64());
    }

    void LoginBanned::WritePacket(BinaryWriter *writer)
    {
        writer->Write(Reason);
        writer->Write(ExpiryDate.ToBinary());
    }

    short LoginSuccess::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::LoginSuccess);
    }

    void LoginSuccess::ReadPacket(BinaryReader *reader)
    {
        int count = reader->ReadInt32();

        for (int i = 0; i < count; i++)
        {
            SelectInfo tempVar(reader);
            Characters.push_back(&tempVar);
        }
    }

    void LoginSuccess::WritePacket(BinaryWriter *writer)
    {
        writer->Write(Characters.size());

        for (int i = 0; i < Characters.size(); i++)
        {
            Characters[i]->Save(writer);
        }
    }

    short NewCharacter::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::NewCharacter);
    }

    void NewCharacter::ReadPacket(BinaryReader *reader)
    {
        Result = reader->ReadByte();
    }

    void NewCharacter::WritePacket(BinaryWriter *writer)
    {
        writer->Write(Result);
    }

    short NewCharacterSuccess::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::NewCharacterSuccess);
    }

    void NewCharacterSuccess::ReadPacket(BinaryReader *reader)
    {
        CharInfo = new SelectInfo(reader);
    }

    void NewCharacterSuccess::WritePacket(BinaryWriter *writer)
    {
        CharInfo->Save(writer);
    }

    short DeleteCharacter::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::DeleteCharacter);
    }

    void DeleteCharacter::ReadPacket(BinaryReader *reader)
    {
        Result = reader->ReadByte();
    }

    void DeleteCharacter::WritePacket(BinaryWriter *writer)
    {
        writer->Write(Result);
    }

    short DeleteCharacterSuccess::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::DeleteCharacterSuccess);
    }

    void DeleteCharacterSuccess::ReadPacket(BinaryReader *reader)
    {
        CharacterIndex = reader->ReadInt32();
    }

    void DeleteCharacterSuccess::WritePacket(BinaryWriter *writer)
    {
        writer->Write(CharacterIndex);
    }

    short StartGame::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::StartGame);
    }

    void StartGame::ReadPacket(BinaryReader *reader)
    {
        Result = reader->ReadByte();
        Resolution = reader->ReadInt32();
    }

    void StartGame::WritePacket(BinaryWriter *writer)
    {
        writer->Write(Result);
        writer->Write(Resolution);
    }

    short StartGameBanned::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::StartGameBanned);
    }

    void StartGameBanned::ReadPacket(BinaryReader *reader)
    {
        Reason = reader->ReadString();
        ExpiryDate = DateTime::FromBinary(reader->ReadInt64());
    }

    void StartGameBanned::WritePacket(BinaryWriter *writer)
    {
        writer->Write(Reason);
        writer->Write(ExpiryDate.ToBinary());
    }

    short StartGameDelay::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::StartGameDelay);
    }

    void StartGameDelay::ReadPacket(BinaryReader *reader)
    {
        Milliseconds = reader->ReadInt64();
    }

    void StartGameDelay::WritePacket(BinaryWriter *writer)
    {
        writer->Write(Milliseconds);
    }

    short MapInformation::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::MapInformation);
    }

    void MapInformation::ReadPacket(BinaryReader *reader)
    {
        FileName = reader->ReadString();
        Title = reader->ReadString();
        MiniMap = reader->ReadUInt16();
        BigMap = reader->ReadUInt16();
        Lights = static_cast<LightSetting>(reader->ReadByte());
        unsigned char bools = reader->ReadByte();
        if ((bools & 0x01) == 0x01)
        {
            Lightning = true;
        }
        if ((bools & 0x02) == 0x02)
        {
            Fire = true;
        }
        MapDarkLight = reader->ReadByte();
        Music = reader->ReadUInt16();
    }

    void MapInformation::WritePacket(BinaryWriter *writer)
    {
        writer->Write(FileName);
        writer->Write(Title);
        writer->Write(MiniMap);
        writer->Write(BigMap);
        writer->Write(static_cast<unsigned char>(Lights));
        unsigned char bools = 0;
        bools |= static_cast<unsigned char>(Lightning ? 0x01 : 0);
        bools |= static_cast<unsigned char>(Fire ? 0x02 : 0);
        writer->Write(bools);
        writer->Write(MapDarkLight);
        writer->Write(Music);
    }

    short UserInformation::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::UserInformation);
    }

    void UserInformation::ReadPacket(BinaryReader *reader)
    {
        ObjectID = reader->ReadUInt32();
        RealId = reader->ReadUInt32();
        Name = reader->ReadString();
        GuildName = reader->ReadString();
        GuildRank = reader->ReadString();
        NameColour = Color::FromArgb(reader->ReadInt32());
        Class = static_cast<MirClass>(reader->ReadByte());
        Gender = static_cast<MirGender>(reader->ReadByte());
        Level = reader->ReadUInt16();
        Location = new Point(reader->ReadInt32(), reader->ReadInt32());
        Direction = static_cast<MirDirection>(reader->ReadByte());
        Hair = reader->ReadByte();
        HP = reader->ReadInt32();
        MP = reader->ReadInt32();

        Experience = reader->ReadInt64();
        MaxExperience = reader->ReadInt64();

        LevelEffects = static_cast<LevelEffects>(reader->ReadByte());

        if (reader->ReadBoolean())
        {
            Inventory = std::vector<UserItem*>(reader->ReadInt32());
            for (int i = 0; i < Inventory.size(); i++)
            {
                if (!reader->ReadBoolean())
                {
                    continue;
                }
                Inventory[i] = new UserItem(reader);
            }
        }

        if (reader->ReadBoolean())
        {
            Equipment = std::vector<UserItem*>(reader->ReadInt32());
            for (int i = 0; i < Equipment.size(); i++)
            {
                if (!reader->ReadBoolean())
                {
                    continue;
                }
                Equipment[i] = new UserItem(reader);
            }
        }

        if (reader->ReadBoolean())
        {
            QuestInventory = std::vector<UserItem*>(reader->ReadInt32());
            for (int i = 0; i < QuestInventory.size(); i++)
            {
                if (!reader->ReadBoolean())
                {
                    continue;
                }
                QuestInventory[i] = new UserItem(reader);
            }
        }

        Gold = reader->ReadUInt32();
        Credit = reader->ReadUInt32();

        HasExpandedStorage = reader->ReadBoolean();
        ExpandedStorageExpiryTime = DateTime::FromBinary(reader->ReadInt64());

        int count = reader->ReadInt32();

        for (int i = 0; i < count; i++)
        {
            ClientMagic tempVar(reader);
            Magics.push_back(&tempVar);
        }

        //IntelligentCreature
        count = reader->ReadInt32();
        for (int i = 0; i < count; i++)
        {
            ClientIntelligentCreature tempVar2(reader);
            IntelligentCreatures.push_back(&tempVar2);
        }
        SummonedCreatureType = static_cast<IntelligentCreatureType>(reader->ReadByte());
        CreatureSummoned = reader->ReadBoolean();
    }

    void UserInformation::WritePacket(BinaryWriter *writer)
    {
        writer->Write(ObjectID);
        writer->Write(RealId);
        writer->Write(Name);
        writer->Write(GuildName);
        writer->Write(GuildRank);
        writer->Write(NameColour->ToArgb());
        writer->Write(static_cast<unsigned char>(Class));
        writer->Write(static_cast<unsigned char>(Gender));
        writer->Write(Level);
        writer->Write(Location->X);
        writer->Write(Location->Y);
        writer->Write(static_cast<unsigned char>(Direction));
        writer->Write(Hair);
        writer->Write(HP);
        writer->Write(MP);

        writer->Write(Experience);
        writer->Write(MaxExperience);

        writer->Write(static_cast<unsigned char>(LevelEffects));

        writer->Write(!Inventory.empty());
        if (!Inventory.empty())
        {
            writer->Write(Inventory.size());
            for (int i = 0; i < Inventory.size(); i++)
            {
                writer->Write(Inventory[i] != nullptr);
                if (Inventory[i] == nullptr)
                {
                    continue;
                }

                Inventory[i]->Save(writer);
            }

        }

        writer->Write(!Equipment.empty());
        if (!Equipment.empty())
        {
            writer->Write(Equipment.size());
            for (int i = 0; i < Equipment.size(); i++)
            {
                writer->Write(Equipment[i] != nullptr);
                if (Equipment[i] == nullptr)
                {
                    continue;
                }

                Equipment[i]->Save(writer);
            }
        }

        writer->Write(!QuestInventory.empty());
        if (!QuestInventory.empty())
        {
            writer->Write(QuestInventory.size());
            for (int i = 0; i < QuestInventory.size(); i++)
            {
                writer->Write(QuestInventory[i] != nullptr);
                if (QuestInventory[i] == nullptr)
                {
                    continue;
                }

                QuestInventory[i]->Save(writer);
            }
        }

        writer->Write(Gold);
        writer->Write(Credit);

        writer->Write(HasExpandedStorage);
        writer->Write(ExpandedStorageExpiryTime.ToBinary());

        writer->Write(Magics.size());
        for (int i = 0; i < Magics.size(); i++)
        {
            Magics[i]->Save(writer);
        }

        //IntelligentCreature
        writer->Write(IntelligentCreatures.size());
        for (int i = 0; i < IntelligentCreatures.size(); i++)
        {
            IntelligentCreatures[i]->Save(writer);
        }
        writer->Write(static_cast<unsigned char>(SummonedCreatureType));
        writer->Write(CreatureSummoned);
    }

    short UserSlotsRefresh::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::UserSlotsRefresh);
    }

    void UserSlotsRefresh::ReadPacket(BinaryReader *reader)
    {

        if (reader->ReadBoolean())
        {
            Inventory = std::vector<UserItem*>(reader->ReadInt32());
            for (int i = 0; i < Inventory.size(); i++)
            {
                if (!reader->ReadBoolean())
                {
                    continue;
                }
                Inventory[i] = new UserItem(reader);
            }
        }

        if (reader->ReadBoolean())
        {
            Equipment = std::vector<UserItem*>(reader->ReadInt32());
            for (int i = 0; i < Equipment.size(); i++)
            {
                if (!reader->ReadBoolean())
                {
                    continue;
                }
                Equipment[i] = new UserItem(reader);
            }
        }
    }

    void UserSlotsRefresh::WritePacket(BinaryWriter *writer)
    {
        writer->Write(!Inventory.empty());
        if (!Inventory.empty())
        {
            writer->Write(Inventory.size());
            for (int i = 0; i < Inventory.size(); i++)
            {
                writer->Write(Inventory[i] != nullptr);
                if (Inventory[i] == nullptr)
                {
                    continue;
                }

                Inventory[i]->Save(writer);
            }

        }

        writer->Write(!Equipment.empty());
        if (!Equipment.empty())
        {
            writer->Write(Equipment.size());
            for (int i = 0; i < Equipment.size(); i++)
            {
                writer->Write(Equipment[i] != nullptr);
                if (Equipment[i] == nullptr)
                {
                    continue;
                }

                Equipment[i]->Save(writer);
            }
        }
    }

    short UserLocation::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::UserLocation);
    }

    void UserLocation::ReadPacket(BinaryReader *reader)
    {
        Location = new Point(reader->ReadInt32(), reader->ReadInt32());
        Direction = static_cast<MirDirection>(reader->ReadByte());
    }

    void UserLocation::WritePacket(BinaryWriter *writer)
    {
        writer->Write(Location->X);
        writer->Write(Location->Y);
        writer->Write(static_cast<unsigned char>(Direction));
    }

    short ObjectPlayer::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::ObjectPlayer);
    }

    void ObjectPlayer::ReadPacket(BinaryReader *reader)
    {
        ObjectID = reader->ReadUInt32();
        Name = reader->ReadString();
        GuildName = reader->ReadString();
        GuildRankName = reader->ReadString();
        NameColour = Color::FromArgb(reader->ReadInt32());
        Class = static_cast<MirClass>(reader->ReadByte());
        Gender = static_cast<MirGender>(reader->ReadByte());
        Level = reader->ReadUInt16();
        Location = new Point(reader->ReadInt32(), reader->ReadInt32());
        Direction = static_cast<MirDirection>(reader->ReadByte());
        Hair = reader->ReadByte();
        Light = reader->ReadByte();
        Weapon = reader->ReadInt16();
        WeaponEffect = reader->ReadInt16();
        Armour = reader->ReadInt16();
        Poison = static_cast<PoisonType>(reader->ReadUInt16());
        Dead = reader->ReadBoolean();
        Hidden = reader->ReadBoolean();
        Effect = static_cast<SpellEffect>(reader->ReadByte());
        WingEffect = reader->ReadByte();
        Extra = reader->ReadBoolean();
        MountType = reader->ReadInt16();
        RidingMount = reader->ReadBoolean();
        Fishing = reader->ReadBoolean();

        TransformType = reader->ReadInt16();

        ElementOrbEffect = reader->ReadUInt32();
        ElementOrbLvl = reader->ReadUInt32();
        ElementOrbMax = reader->ReadUInt32();

        int count = reader->ReadInt32();
        for (int i = 0; i < count; i++)
        {
            Buffs.push_back(static_cast<BuffType>(reader->ReadByte()));
        }

        LevelEffects = static_cast<LevelEffects>(reader->ReadByte());
    }

    void ObjectPlayer::WritePacket(BinaryWriter *writer)
    {
        writer->Write(ObjectID);
        writer->Write(Name);
        writer->Write(GuildName);
        writer->Write(GuildRankName);
        writer->Write(NameColour->ToArgb());
        writer->Write(static_cast<unsigned char>(Class));
        writer->Write(static_cast<unsigned char>(Gender));
        writer->Write(Level);
        writer->Write(Location->X);
        writer->Write(Location->Y);
        writer->Write(static_cast<unsigned char>(Direction));
        writer->Write(Hair);
        writer->Write(Light);
        writer->Write(Weapon);
        writer->Write(WeaponEffect);
        writer->Write(Armour);
        writer->Write(static_cast<unsigned short>(Poison));
        writer->Write(Dead);
        writer->Write(Hidden);
        writer->Write(static_cast<unsigned char>(Effect));
        writer->Write(WingEffect);
        writer->Write(Extra);
        writer->Write(MountType);
        writer->Write(RidingMount);
        writer->Write(Fishing);

        writer->Write(TransformType);

        writer->Write(ElementOrbEffect);
        writer->Write(ElementOrbLvl);
        writer->Write(ElementOrbMax);

        writer->Write(Buffs.size());
        for (int i = 0; i < Buffs.size(); i++)
        {
            writer->Write(static_cast<unsigned char>(Buffs[i]));
        }

        writer->Write(static_cast<unsigned char>(LevelEffects));
    }

    short ObjectRemove::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::ObjectRemove);
    }

    void ObjectRemove::ReadPacket(BinaryReader *reader)
    {
        ObjectID = reader->ReadUInt32();
    }

    void ObjectRemove::WritePacket(BinaryWriter *writer)
    {
        writer->Write(ObjectID);
    }

    short ObjectTurn::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::ObjectTurn);
    }

    void ObjectTurn::ReadPacket(BinaryReader *reader)
    {
        ObjectID = reader->ReadUInt32();
        Location = new Point(reader->ReadInt32(), reader->ReadInt32());
        Direction = static_cast<MirDirection>(reader->ReadByte());
    }

    void ObjectTurn::WritePacket(BinaryWriter *writer)
    {
        writer->Write(ObjectID);
        writer->Write(Location->X);
        writer->Write(Location->Y);
        writer->Write(static_cast<unsigned char>(Direction));
    }

    short ObjectWalk::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::ObjectWalk);
    }

    void ObjectWalk::ReadPacket(BinaryReader *reader)
    {
        ObjectID = reader->ReadUInt32();
        Location = new Point(reader->ReadInt32(), reader->ReadInt32());
        Direction = static_cast<MirDirection>(reader->ReadByte());
    }

    void ObjectWalk::WritePacket(BinaryWriter *writer)
    {
        writer->Write(ObjectID);
        writer->Write(Location->X);
        writer->Write(Location->Y);
        writer->Write(static_cast<unsigned char>(Direction));
    }

    short ObjectRun::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::ObjectRun);
    }

    void ObjectRun::ReadPacket(BinaryReader *reader)
    {
        ObjectID = reader->ReadUInt32();
        Location = new Point(reader->ReadInt32(), reader->ReadInt32());
        Direction = static_cast<MirDirection>(reader->ReadByte());
    }

    void ObjectRun::WritePacket(BinaryWriter *writer)
    {
        writer->Write(ObjectID);
        writer->Write(Location->X);
        writer->Write(Location->Y);
        writer->Write(static_cast<unsigned char>(Direction));
    }

    short Chat::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::Chat);
    }

    void Chat::ReadPacket(BinaryReader *reader)
    {
        Message = reader->ReadString();
        Type = static_cast<ChatType>(reader->ReadByte());
    }

    void Chat::WritePacket(BinaryWriter *writer)
    {
        writer->Write(Message);
        writer->Write(static_cast<unsigned char>(Type));
    }

    short ObjectChat::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::ObjectChat);
    }

    void ObjectChat::ReadPacket(BinaryReader *reader)
    {
        ObjectID = reader->ReadUInt32();
        Text = reader->ReadString();
        Type = static_cast<ChatType>(reader->ReadByte());
    }

    void ObjectChat::WritePacket(BinaryWriter *writer)
    {
        writer->Write(ObjectID);
        writer->Write(Text);
        writer->Write(static_cast<unsigned char>(Type));
    }

    short NewItemInfo::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::NewItemInfo);
    }

    void NewItemInfo::ReadPacket(BinaryReader *reader)
    {
        Info = new ItemInfo(reader);
    }

    void NewItemInfo::WritePacket(BinaryWriter *writer)
    {
        Info->Save(writer);
    }

    short NewChatItem::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::NewChatItem);
    }

    void NewChatItem::ReadPacket(BinaryReader *reader)
    {
        Item = new UserItem(reader);
    }

    void NewChatItem::WritePacket(BinaryWriter *writer)
    {
        Item->Save(writer);
    }

    short MoveItem::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::MoveItem);
    }

    void MoveItem::ReadPacket(BinaryReader *reader)
    {
        Grid = static_cast<MirGridType>(reader->ReadByte());
        From = reader->ReadInt32();
        To = reader->ReadInt32();
        Success = reader->ReadBoolean();
    }

    void MoveItem::WritePacket(BinaryWriter *writer)
    {
        writer->Write(static_cast<unsigned char>(Grid));
        writer->Write(From);
        writer->Write(To);
        writer->Write(Success);
    }

    short EquipItem::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::EquipItem);
    }

    void EquipItem::ReadPacket(BinaryReader *reader)
    {
        Grid = static_cast<MirGridType>(reader->ReadByte());
        UniqueID = reader->ReadUInt64();
        To = reader->ReadInt32();
        Success = reader->ReadBoolean();
    }

    void EquipItem::WritePacket(BinaryWriter *writer)
    {
        writer->Write(static_cast<unsigned char>(Grid));
        writer->Write(UniqueID);
        writer->Write(To);
        writer->Write(Success);
    }

    short MergeItem::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::MergeItem);
    }

    void MergeItem::ReadPacket(BinaryReader *reader)
    {
        GridFrom = static_cast<MirGridType>(reader->ReadByte());
        GridTo = static_cast<MirGridType>(reader->ReadByte());
        IDFrom = reader->ReadUInt64();
        IDTo = reader->ReadUInt64();
        Success = reader->ReadBoolean();
    }

    void MergeItem::WritePacket(BinaryWriter *writer)
    {
        writer->Write(static_cast<unsigned char>(GridFrom));
        writer->Write(static_cast<unsigned char>(GridTo));
        writer->Write(IDFrom);
        writer->Write(IDTo);
        writer->Write(Success);
    }

    short RemoveItem::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::RemoveItem);
    }

    void RemoveItem::ReadPacket(BinaryReader *reader)
    {
        Grid = static_cast<MirGridType>(reader->ReadByte());
        UniqueID = reader->ReadUInt64();
        To = reader->ReadInt32();
        Success = reader->ReadBoolean();
    }

    void RemoveItem::WritePacket(BinaryWriter *writer)
    {
        writer->Write(static_cast<unsigned char>(Grid));
        writer->Write(UniqueID);
        writer->Write(To);
        writer->Write(Success);
    }

    short RemoveSlotItem::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::RemoveSlotItem);
    }

    void RemoveSlotItem::ReadPacket(BinaryReader *reader)
    {
        Grid = static_cast<MirGridType>(reader->ReadByte());
        GridTo = static_cast<MirGridType>(reader->ReadByte());
        UniqueID = reader->ReadUInt64();
        To = reader->ReadInt32();
        Success = reader->ReadBoolean();
    }

    void RemoveSlotItem::WritePacket(BinaryWriter *writer)
    {
        writer->Write(static_cast<unsigned char>(Grid));
        writer->Write(static_cast<unsigned char>(GridTo));
        writer->Write(UniqueID);
        writer->Write(To);
        writer->Write(Success);
    }

    short TakeBackItem::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::TakeBackItem);
    }

    void TakeBackItem::ReadPacket(BinaryReader *reader)
    {
        From = reader->ReadInt32();
        To = reader->ReadInt32();
        Success = reader->ReadBoolean();
    }

    void TakeBackItem::WritePacket(BinaryWriter *writer)
    {
        writer->Write(From);
        writer->Write(To);
        writer->Write(Success);
    }

    short StoreItem::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::StoreItem);
    }

    void StoreItem::ReadPacket(BinaryReader *reader)
    {
        From = reader->ReadInt32();
        To = reader->ReadInt32();
        Success = reader->ReadBoolean();
    }

    void StoreItem::WritePacket(BinaryWriter *writer)
    {
        writer->Write(From);
        writer->Write(To);
        writer->Write(Success);
    }

    short DepositRefineItem::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::DepositRefineItem);
    }

    void DepositRefineItem::ReadPacket(BinaryReader *reader)
    {
        From = reader->ReadInt32();
        To = reader->ReadInt32();
        Success = reader->ReadBoolean();
    }

    void DepositRefineItem::WritePacket(BinaryWriter *writer)
    {
        writer->Write(From);
        writer->Write(To);
        writer->Write(Success);
    }

    short RetrieveRefineItem::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::RetrieveRefineItem);
    }

    void RetrieveRefineItem::ReadPacket(BinaryReader *reader)
    {
        From = reader->ReadInt32();
        To = reader->ReadInt32();
        Success = reader->ReadBoolean();
    }

    void RetrieveRefineItem::WritePacket(BinaryWriter *writer)
    {
        writer->Write(From);
        writer->Write(To);
        writer->Write(Success);
    }

    short RefineCancel::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::RefineCancel);
    }

    void RefineCancel::ReadPacket(BinaryReader *reader)
    {
        Unlock = reader->ReadBoolean();
    }

    void RefineCancel::WritePacket(BinaryWriter *writer)
    {
        writer->Write(Unlock);
    }

    short RefineItem::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::RefineItem);
    }

    void RefineItem::ReadPacket(BinaryReader *reader)
    {
        UniqueID = reader->ReadUInt64();
    }

    void RefineItem::WritePacket(BinaryWriter *writer)
    {
        writer->Write(UniqueID);
    }

    short DepositTradeItem::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::DepositTradeItem);
    }

    void DepositTradeItem::ReadPacket(BinaryReader *reader)
    {
        From = reader->ReadInt32();
        To = reader->ReadInt32();
        Success = reader->ReadBoolean();
    }

    void DepositTradeItem::WritePacket(BinaryWriter *writer)
    {
        writer->Write(From);
        writer->Write(To);
        writer->Write(Success);
    }

    short RetrieveTradeItem::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::RetrieveTradeItem);
    }

    void RetrieveTradeItem::ReadPacket(BinaryReader *reader)
    {
        From = reader->ReadInt32();
        To = reader->ReadInt32();
        Success = reader->ReadBoolean();
    }

    void RetrieveTradeItem::WritePacket(BinaryWriter *writer)
    {
        writer->Write(From);
        writer->Write(To);
        writer->Write(Success);
    }

    short SplitItem::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::SplitItem);
    }

    void SplitItem::ReadPacket(BinaryReader *reader)
    {
        if (reader->ReadBoolean())
        {
            Item = new UserItem(reader);
        }

        Grid = static_cast<MirGridType>(reader->ReadByte());
    }

    void SplitItem::WritePacket(BinaryWriter *writer)
    {
        writer->Write(Item != nullptr);
        if (Item != nullptr)
        {
            Item->Save(writer);
        }
        writer->Write(static_cast<unsigned char>(Grid));
    }

    short SplitItem1::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::SplitItem1);
    }

    void SplitItem1::ReadPacket(BinaryReader *reader)
    {
        Grid = static_cast<MirGridType>(reader->ReadByte());
        UniqueID = reader->ReadUInt64();
        Count = reader->ReadUInt16();
        Success = reader->ReadBoolean();
    }

    void SplitItem1::WritePacket(BinaryWriter *writer)
    {
        writer->Write(static_cast<unsigned char>(Grid));
        writer->Write(UniqueID);
        writer->Write(Count);
        writer->Write(Success);
    }

    short UseItem::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::UseItem);
    }

    void UseItem::ReadPacket(BinaryReader *reader)
    {
        UniqueID = reader->ReadUInt64();
        Success = reader->ReadBoolean();
    }

    void UseItem::WritePacket(BinaryWriter *writer)
    {
        writer->Write(UniqueID);
        writer->Write(Success);
    }

    short DropItem::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::DropItem);
    }

    void DropItem::ReadPacket(BinaryReader *reader)
    {
        UniqueID = reader->ReadUInt64();
        Count = reader->ReadUInt16();
        Success = reader->ReadBoolean();
    }

    void DropItem::WritePacket(BinaryWriter *writer)
    {
        writer->Write(UniqueID);
        writer->Write(Count);
        writer->Write(Success);
    }

    short PlayerUpdate::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::PlayerUpdate);
    }

    void PlayerUpdate::ReadPacket(BinaryReader *reader)
    {
        ObjectID = reader->ReadUInt32();

        Light = reader->ReadByte();
        Weapon = reader->ReadInt16();
        WeaponEffect = reader->ReadInt16();
        Armour = reader->ReadInt16();
        WingEffect = reader->ReadByte();
    }

    void PlayerUpdate::WritePacket(BinaryWriter *writer)
    {
        writer->Write(ObjectID);

        writer->Write(Light);
        writer->Write(Weapon);
        writer->Write(WeaponEffect);
        writer->Write(Armour);
        writer->Write(WingEffect);
    }

    short PlayerInspect::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::PlayerInspect);
    }

    void PlayerInspect::ReadPacket(BinaryReader *reader)
    {
        Name = reader->ReadString();
        GuildName = reader->ReadString();
        GuildRank = reader->ReadString();
        Equipment = std::vector<UserItem*>(reader->ReadInt32());
        for (int i = 0; i < Equipment.size(); i++)
        {
            if (reader->ReadBoolean())
            {
                Equipment[i] = new UserItem(reader);
            }
        }

        Class = static_cast<MirClass>(reader->ReadByte());
        Gender = static_cast<MirGender>(reader->ReadByte());
        Hair = reader->ReadByte();
        Level = reader->ReadUInt16();
        LoverName = reader->ReadString();
    }

    void PlayerInspect::WritePacket(BinaryWriter *writer)
    {
        writer->Write(Name);
        writer->Write(GuildName);
        writer->Write(GuildRank);
        writer->Write(Equipment.size());
        for (int i = 0; i < Equipment.size(); i++)
        {
            UserItem *T = Equipment[i];
            writer->Write(T != nullptr);
            if (T != nullptr)
            {
                T->Save(writer);
            }
        }

        writer->Write(static_cast<unsigned char>(Class));
        writer->Write(static_cast<unsigned char>(Gender));
        writer->Write(Hair);
        writer->Write(Level);
        writer->Write(LoverName);

    }

    short MarriageRequest::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::MarriageRequest);
    }

    void MarriageRequest::ReadPacket(BinaryReader *reader)
    {
        Name = reader->ReadString();
    }

    void MarriageRequest::WritePacket(BinaryWriter *writer)
    {
        writer->Write(Name);
    }

    short DivorceRequest::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::DivorceRequest);
    }

    void DivorceRequest::ReadPacket(BinaryReader *reader)
    {
        Name = reader->ReadString();
    }

    void DivorceRequest::WritePacket(BinaryWriter *writer)
    {
        writer->Write(Name);
    }

    short MentorRequest::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::MentorRequest);
    }

    void MentorRequest::ReadPacket(BinaryReader *reader)
    {
        Name = reader->ReadString();
        Level = reader->ReadUInt16();
    }

    void MentorRequest::WritePacket(BinaryWriter *writer)
    {
        writer->Write(Name);
        writer->Write(Level);
    }

    short TradeRequest::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::TradeRequest);
    }

    void TradeRequest::ReadPacket(BinaryReader *reader)
    {
        Name = reader->ReadString();
    }

    void TradeRequest::WritePacket(BinaryWriter *writer)
    {
        writer->Write(Name);
    }

    short TradeAccept::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::TradeAccept);
    }

    void TradeAccept::ReadPacket(BinaryReader *reader)
    {
        Name = reader->ReadString();
    }

    void TradeAccept::WritePacket(BinaryWriter *writer)
    {
        writer->Write(Name);
    }

    short TradeGold::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::TradeGold);
    }

    void TradeGold::ReadPacket(BinaryReader *reader)
    {
        Amount = reader->ReadUInt32();
    }

    void TradeGold::WritePacket(BinaryWriter *writer)
    {
        writer->Write(Amount);
    }

    short TradeItem::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::TradeItem);
    }

    void TradeItem::ReadPacket(BinaryReader *reader)
    {
        TradeItems = std::vector<UserItem*>(reader->ReadInt32());
        for (int i = 0; i < TradeItems.size(); i++)
        {
            if (reader->ReadBoolean())
            {
                TradeItems[i] = new UserItem(reader);
            }
        }
    }

    void TradeItem::WritePacket(BinaryWriter *writer)
    {
        writer->Write(TradeItems.size());
        for (int i = 0; i < TradeItems.size(); i++)
        {
            UserItem *T = TradeItems[i];
            writer->Write(T != nullptr);
            if (T != nullptr)
            {
                T->Save(writer);
            }
        }
    }

    short TradeConfirm::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::TradeConfirm);
    }

    void TradeConfirm::ReadPacket(BinaryReader *reader)
    {
    }

    void TradeConfirm::WritePacket(BinaryWriter *writer)
    {
    }

    short TradeCancel::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::TradeCancel);
    }

    void TradeCancel::ReadPacket(BinaryReader *reader)
    {
        Unlock = reader->ReadBoolean();
    }

    void TradeCancel::WritePacket(BinaryWriter *writer)
    {
        writer->Write(Unlock);
    }

    short LogOutSuccess::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::LogOutSuccess);
    }

    void LogOutSuccess::ReadPacket(BinaryReader *reader)
    {
        int count = reader->ReadInt32();

        for (int i = 0; i < count; i++)
        {
            SelectInfo tempVar(reader);
            Characters.push_back(&tempVar);
        }
    }

    void LogOutSuccess::WritePacket(BinaryWriter *writer)
    {
        writer->Write(Characters.size());

        for (int i = 0; i < Characters.size(); i++)
        {
            Characters[i]->Save(writer);
        }
    }

    short LogOutFailed::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::LogOutFailed);
    }

    void LogOutFailed::ReadPacket(BinaryReader *reader)
    {
    }

    void LogOutFailed::WritePacket(BinaryWriter *writer)
    {
    }

    short TimeOfDay::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::TimeOfDay);
    }

    void TimeOfDay::ReadPacket(BinaryReader *reader)
    {
        Lights = static_cast<LightSetting>(reader->ReadByte());
    }

    void TimeOfDay::WritePacket(BinaryWriter *writer)
    {
        writer->Write(static_cast<unsigned char>(Lights));
    }

    short ChangeAMode::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::ChangeAMode);
    }

    void ChangeAMode::ReadPacket(BinaryReader *reader)
    {
        Mode = static_cast<AttackMode>(reader->ReadByte());
    }

    void ChangeAMode::WritePacket(BinaryWriter *writer)
    {
        writer->Write(static_cast<unsigned char>(Mode));
    }

    short ChangePMode::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::ChangePMode);
    }

    void ChangePMode::ReadPacket(BinaryReader *reader)
    {
        Mode = static_cast<PetMode>(reader->ReadByte());
    }

    void ChangePMode::WritePacket(BinaryWriter *writer)
    {
        writer->Write(static_cast<unsigned char>(Mode));
    }

    short ObjectItem::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::ObjectItem);
    }

    void ObjectItem::ReadPacket(BinaryReader *reader)
    {
        ObjectID = reader->ReadUInt32();
        Name = reader->ReadString();
        NameColour = Color::FromArgb(reader->ReadInt32());
        Location = new Point(reader->ReadInt32(), reader->ReadInt32());
        Image = reader->ReadUInt16();
        grade = static_cast<ItemGrade>(reader->ReadByte());
    }

    void ObjectItem::WritePacket(BinaryWriter *writer)
    {
        writer->Write(ObjectID);
        writer->Write(Name);
        writer->Write(NameColour->ToArgb());
        writer->Write(Location->X);
        writer->Write(Location->Y);
        writer->Write(Image);
        writer->Write(static_cast<unsigned char>(grade));
    }

    short ObjectGold::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::ObjectGold);
    }

    void ObjectGold::ReadPacket(BinaryReader *reader)
    {
        ObjectID = reader->ReadUInt32();
        Gold = reader->ReadUInt32();
        Location = new Point(reader->ReadInt32(), reader->ReadInt32());
    }

    void ObjectGold::WritePacket(BinaryWriter *writer)
    {
        writer->Write(ObjectID);
        writer->Write(Gold);
        writer->Write(Location->X);
        writer->Write(Location->Y);
    }

    short GainedItem::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::GainedItem);
    }

    void GainedItem::ReadPacket(BinaryReader *reader)
    {
        Item = new UserItem(reader);
    }

    void GainedItem::WritePacket(BinaryWriter *writer)
    {
        Item->Save(writer);
    }

    short GainedGold::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::GainedGold);
    }

    void GainedGold::ReadPacket(BinaryReader *reader)
    {
        Gold = reader->ReadUInt32();
    }

    void GainedGold::WritePacket(BinaryWriter *writer)
    {
        writer->Write(Gold);
    }

    short LoseGold::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::LoseGold);
    }

    void LoseGold::ReadPacket(BinaryReader *reader)
    {
        Gold = reader->ReadUInt32();
    }

    void LoseGold::WritePacket(BinaryWriter *writer)
    {
        writer->Write(Gold);
    }

    short GainedCredit::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::GainedCredit);
    }

    void GainedCredit::ReadPacket(BinaryReader *reader)
    {
        Credit = reader->ReadUInt32();
    }

    void GainedCredit::WritePacket(BinaryWriter *writer)
    {
        writer->Write(Credit);
    }

    short LoseCredit::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::LoseCredit);
    }

    void LoseCredit::ReadPacket(BinaryReader *reader)
    {
        Credit = reader->ReadUInt32();
    }

    void LoseCredit::WritePacket(BinaryWriter *writer)
    {
        writer->Write(Credit);
    }

    short ObjectMonster::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::ObjectMonster);
    }

    void ObjectMonster::ReadPacket(BinaryReader *reader)
    {
        ObjectID = reader->ReadUInt32();
        Name = reader->ReadString();
        NameColour = Color::FromArgb(reader->ReadInt32());
        Location = new Point(reader->ReadInt32(), reader->ReadInt32());
        Image = static_cast<Monster>(reader->ReadUInt16());
        Direction = static_cast<MirDirection>(reader->ReadByte());
        Effect = reader->ReadByte();
        AI = reader->ReadByte();
        Light = reader->ReadByte();
        Dead = reader->ReadBoolean();
        Skeleton = reader->ReadBoolean();
        Poison = static_cast<PoisonType>(reader->ReadUInt16());
        Hidden = reader->ReadBoolean();
        ShockTime = reader->ReadInt64();
        BindingShotCenter = reader->ReadBoolean();
        Extra = reader->ReadBoolean();
        ExtraByte = reader->ReadByte();

        int count = reader->ReadInt32();
        for (int i = 0; i < count; i++)
        {
            Buffs.push_back(static_cast<BuffType>(reader->ReadByte()));
        }
    }

    void ObjectMonster::WritePacket(BinaryWriter *writer)
    {
        writer->Write(ObjectID);
        writer->Write(Name);
        writer->Write(NameColour->ToArgb());
        writer->Write(Location->X);
        writer->Write(Location->Y);
        writer->Write(static_cast<unsigned short>(Image));
        writer->Write(static_cast<unsigned char>(Direction));
        writer->Write(Effect);
        writer->Write(AI);
        writer->Write(Light);
        writer->Write(Dead);
        writer->Write(Skeleton);
        writer->Write(static_cast<unsigned short>(Poison));
        writer->Write(Hidden);
        writer->Write(ShockTime);
        writer->Write(BindingShotCenter);
        writer->Write(Extra);
        writer->Write(static_cast<unsigned char>(ExtraByte));

        writer->Write(Buffs.size());
        for (int i = 0; i < Buffs.size(); i++)
        {
            writer->Write(static_cast<unsigned char>(Buffs[i]));
        }
    }

    short ObjectAttack::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::ObjectAttack);
    }

    void ObjectAttack::ReadPacket(BinaryReader *reader)
    {
        ObjectID = reader->ReadUInt32();
        Location = new Point(reader->ReadInt32(), reader->ReadInt32());
        Direction = static_cast<MirDirection>(reader->ReadByte());
        Spell = static_cast<Spell>(reader->ReadByte());
        Level = reader->ReadByte();
        Type = reader->ReadByte();
    }

    void ObjectAttack::WritePacket(BinaryWriter *writer)
    {
        writer->Write(ObjectID);
        writer->Write(Location->X);
        writer->Write(Location->Y);
        writer->Write(static_cast<unsigned char>(Direction));
        writer->Write(static_cast<unsigned char>(Spell));
        writer->Write(Level);
        writer->Write(Type);
    }

    short Struck::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::Struck);
    }

    void Struck::ReadPacket(BinaryReader *reader)
    {
        AttackerID = reader->ReadUInt32();
    }

    void Struck::WritePacket(BinaryWriter *writer)
    {
        writer->Write(AttackerID);
    }

    short ObjectStruck::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::ObjectStruck);
    }

    void ObjectStruck::ReadPacket(BinaryReader *reader)
    {
        ObjectID = reader->ReadUInt32();
        AttackerID = reader->ReadUInt32();
        Location = new Point(reader->ReadInt32(), reader->ReadInt32());
        Direction = static_cast<MirDirection>(reader->ReadByte());
    }

    void ObjectStruck::WritePacket(BinaryWriter *writer)
    {
        writer->Write(ObjectID);
        writer->Write(AttackerID);
        writer->Write(Location->X);
        writer->Write(Location->Y);
        writer->Write(static_cast<unsigned char>(Direction));
    }

    short DamageIndicator::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::DamageIndicator);
    }

    void DamageIndicator::ReadPacket(BinaryReader *reader)
    {
        Damage = reader->ReadInt32();
        Type = static_cast<DamageType>(reader->ReadByte());
        ObjectID = reader->ReadUInt32();
    }

    void DamageIndicator::WritePacket(BinaryWriter *writer)
    {
        writer->Write(Damage);
        writer->Write(static_cast<unsigned char>(Type));
        writer->Write(ObjectID);
    }

    short DuraChanged::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::DuraChanged);
    }

    void DuraChanged::ReadPacket(BinaryReader *reader)
    {
        UniqueID = reader->ReadUInt64();
        CurrentDura = reader->ReadUInt16();
    }

    void DuraChanged::WritePacket(BinaryWriter *writer)
    {
        writer->Write(UniqueID);
        writer->Write(CurrentDura);
    }

    short HealthChanged::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::HealthChanged);
    }

    void HealthChanged::ReadPacket(BinaryReader *reader)
    {
        HP = reader->ReadInt32();
        MP = reader->ReadInt32();
    }

    void HealthChanged::WritePacket(BinaryWriter *writer)
    {
        writer->Write(HP);
        writer->Write(MP);
    }

    short DeleteItem::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::DeleteItem);
    }

    void DeleteItem::ReadPacket(BinaryReader *reader)
    {
        UniqueID = reader->ReadUInt64();
        Count = reader->ReadUInt16();
    }

    void DeleteItem::WritePacket(BinaryWriter *writer)
    {
        writer->Write(UniqueID);
        writer->Write(Count);
    }

    short Death::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::Death);
    }

    void Death::ReadPacket(BinaryReader *reader)
    {
        Location = new Point(reader->ReadInt32(), reader->ReadInt32());
        Direction = static_cast<MirDirection>(reader->ReadByte());
    }

    void Death::WritePacket(BinaryWriter *writer)
    {
        writer->Write(Location->X);
        writer->Write(Location->Y);
        writer->Write(static_cast<unsigned char>(Direction));
    }

    short ObjectDied::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::ObjectDied);
    }

    void ObjectDied::ReadPacket(BinaryReader *reader)
    {
        ObjectID = reader->ReadUInt32();
        Location = new Point(reader->ReadInt32(), reader->ReadInt32());
        Direction = static_cast<MirDirection>(reader->ReadByte());
        Type = reader->ReadByte();
    }

    void ObjectDied::WritePacket(BinaryWriter *writer)
    {
        writer->Write(ObjectID);
        writer->Write(Location->X);
        writer->Write(Location->Y);
        writer->Write(static_cast<unsigned char>(Direction));
        writer->Write(Type);
    }

    short ColourChanged::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::ColourChanged);
    }

    void ColourChanged::ReadPacket(BinaryReader *reader)
    {
        NameColour = Color::FromArgb(reader->ReadInt32());
    }

    void ColourChanged::WritePacket(BinaryWriter *writer)
    {
        writer->Write(NameColour->ToArgb());
    }

    short ObjectColourChanged::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::ObjectColourChanged);
    }

    void ObjectColourChanged::ReadPacket(BinaryReader *reader)
    {
        ObjectID = reader->ReadUInt32();
        NameColour = Color::FromArgb(reader->ReadInt32());
    }

    void ObjectColourChanged::WritePacket(BinaryWriter *writer)
    {
        writer->Write(ObjectID);
        writer->Write(NameColour->ToArgb());
    }

    short ObjectGuildNameChanged::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::ObjectGuildNameChanged);
    }

    void ObjectGuildNameChanged::ReadPacket(BinaryReader *reader)
    {
        ObjectID = reader->ReadUInt32();
        GuildName = reader->ReadString();
    }

    void ObjectGuildNameChanged::WritePacket(BinaryWriter *writer)
    {
        writer->Write(ObjectID);
        writer->Write(GuildName);
    }

    short GainExperience::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::GainExperience);
    }

    void GainExperience::ReadPacket(BinaryReader *reader)
    {
        Amount = reader->ReadUInt32();
    }

    void GainExperience::WritePacket(BinaryWriter *writer)
    {
        writer->Write(Amount);
    }

    short LevelChanged::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::LevelChanged);
    }

    void LevelChanged::ReadPacket(BinaryReader *reader)
    {
        Level = reader->ReadUInt16();
        Experience = reader->ReadInt64();
        MaxExperience = reader->ReadInt64();
    }

    void LevelChanged::WritePacket(BinaryWriter *writer)
    {
        writer->Write(Level);
        writer->Write(Experience);
        writer->Write(MaxExperience);
    }

    short ObjectLeveled::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::ObjectLeveled);
    }

    void ObjectLeveled::ReadPacket(BinaryReader *reader)
    {
        ObjectID = reader->ReadUInt32();
    }

    void ObjectLeveled::WritePacket(BinaryWriter *writer)
    {
        writer->Write(ObjectID);
    }

    short ObjectHarvest::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::ObjectHarvest);
    }

    void ObjectHarvest::ReadPacket(BinaryReader *reader)
    {
        ObjectID = reader->ReadUInt32();
        Location = new Point(reader->ReadInt32(), reader->ReadInt32());
        Direction = static_cast<MirDirection>(reader->ReadByte());
    }

    void ObjectHarvest::WritePacket(BinaryWriter *writer)
    {
        writer->Write(ObjectID);
        writer->Write(Location->X);
        writer->Write(Location->Y);
        writer->Write(static_cast<unsigned char>(Direction));
    }

    short ObjectHarvested::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::ObjectHarvested);
    }

    void ObjectHarvested::ReadPacket(BinaryReader *reader)
    {
        ObjectID = reader->ReadUInt32();
        Location = new Point(reader->ReadInt32(), reader->ReadInt32());
        Direction = static_cast<MirDirection>(reader->ReadByte());
    }

    void ObjectHarvested::WritePacket(BinaryWriter *writer)
    {
        writer->Write(ObjectID);
        writer->Write(Location->X);
        writer->Write(Location->Y);
        writer->Write(static_cast<unsigned char>(Direction));
    }

    short ObjectNPC::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::ObjectNpc);
    }

    void ObjectNPC::ReadPacket(BinaryReader *reader)
    {
        ObjectID = reader->ReadUInt32();
        Name = reader->ReadString();
        NameColour = Color::FromArgb(reader->ReadInt32());
        Image = reader->ReadUInt16();
        Colour = Color::FromArgb(reader->ReadInt32());
        Location = new Point(reader->ReadInt32(), reader->ReadInt32());
        Direction = static_cast<MirDirection>(reader->ReadByte());

        int count = reader->ReadInt32();

        for (auto i = 0; i < count; i++)
        {
            QuestIDs.push_back(reader->ReadInt32());
        }
    }

    void ObjectNPC::WritePacket(BinaryWriter *writer)
    {
        writer->Write(ObjectID);
        writer->Write(Name);
        writer->Write(NameColour->ToArgb());
        writer->Write(Image);
        writer->Write(Colour->ToArgb());
        writer->Write(Location->X);
        writer->Write(Location->Y);
        writer->Write(static_cast<unsigned char>(Direction));

        writer->Write(QuestIDs.size());

        for (int i = 0; i < QuestIDs.size(); i++)
        {
            writer->Write(QuestIDs[i]);
        }
    }

    short NPCResponse::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::NPCResponse);
    }

    void NPCResponse::ReadPacket(BinaryReader *reader)
    {
        Page = std::vector<std::string>();

        int count = reader->ReadInt32();

        for (int i = 0; i < count; i++)
        {
            Page.push_back(reader->ReadString());
        }
    }

    void NPCResponse::WritePacket(BinaryWriter *writer)
    {
        writer->Write(Page.size());

        for (int i = 0; i < Page.size(); i++)
        {
            writer->Write(Page[i]);
        }
    }

    short ObjectHide::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::ObjectHide);
    }

    void ObjectHide::ReadPacket(BinaryReader *reader)
    {
        ObjectID = reader->ReadUInt32();
    }

    void ObjectHide::WritePacket(BinaryWriter *writer)
    {
        writer->Write(ObjectID);
    }

    short ObjectShow::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::ObjectShow);
    }

    void ObjectShow::ReadPacket(BinaryReader *reader)
    {
        ObjectID = reader->ReadUInt32();
    }

    void ObjectShow::WritePacket(BinaryWriter *writer)
    {
        writer->Write(ObjectID);
    }

    short Poisoned::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::Poisoned);
    }

    void Poisoned::ReadPacket(BinaryReader *reader)
    {
        Poison = static_cast<PoisonType>(reader->ReadUInt16());
    }

    void Poisoned::WritePacket(BinaryWriter *writer)
    {
        writer->Write(static_cast<unsigned short>(Poison));
    }

    short ObjectPoisoned::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::ObjectPoisoned);
    }

    void ObjectPoisoned::ReadPacket(BinaryReader *reader)
    {
        ObjectID = reader->ReadUInt32();
        Poison = static_cast<PoisonType>(reader->ReadUInt16());
    }

    void ObjectPoisoned::WritePacket(BinaryWriter *writer)
    {
        writer->Write(ObjectID);
        writer->Write(static_cast<unsigned short>(Poison));
    }

    short MapChanged::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::MapChanged);
    }

    void MapChanged::ReadPacket(BinaryReader *reader)
    {
        FileName = reader->ReadString();
        Title = reader->ReadString();
        MiniMap = reader->ReadUInt16();
        BigMap = reader->ReadUInt16();
        Lights = static_cast<LightSetting>(reader->ReadByte());
        Location = new Point(reader->ReadInt32(), reader->ReadInt32());
        Direction = static_cast<MirDirection>(reader->ReadByte());
        MapDarkLight = reader->ReadByte();
        Music = reader->ReadUInt16();
    }

    void MapChanged::WritePacket(BinaryWriter *writer)
    {
        writer->Write(FileName);
        writer->Write(Title);
        writer->Write(MiniMap);
        writer->Write(BigMap);
        writer->Write(static_cast<unsigned char>(Lights));
        writer->Write(Location->X);
        writer->Write(Location->Y);
        writer->Write(static_cast<unsigned char>(Direction));
        writer->Write(MapDarkLight);
        writer->Write(Music);
    }

    short ObjectTeleportOut::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::ObjectTeleportOut);
    }

    void ObjectTeleportOut::ReadPacket(BinaryReader *reader)
    {
        ObjectID = reader->ReadUInt32();
        Type = reader->ReadByte();
    }

    void ObjectTeleportOut::WritePacket(BinaryWriter *writer)
    {
        writer->Write(ObjectID);
        writer->Write(Type);
    }

    short ObjectTeleportIn::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::ObjectTeleportIn);
    }

    void ObjectTeleportIn::ReadPacket(BinaryReader *reader)
    {
        ObjectID = reader->ReadUInt32();
        Type = reader->ReadByte();
    }

    void ObjectTeleportIn::WritePacket(BinaryWriter *writer)
    {
        writer->Write(ObjectID);
        writer->Write(Type);
    }

    short TeleportIn::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::TeleportIn);
    }

    void TeleportIn::ReadPacket(BinaryReader *reader)
    {
    }

    void TeleportIn::WritePacket(BinaryWriter *writer)
    {
    }

    short NPCGoods::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::NPCGoods);
    }

    void NPCGoods::ReadPacket(BinaryReader *reader)
    {
        int count = reader->ReadInt32();

        for (int i = 0; i < count; i++)
        {
            UserItem tempVar(reader);
            List.push_back(&tempVar);
        }

        Rate = reader->ReadSingle();
        Type = static_cast<PanelType>(reader->ReadByte());

        HideAddedStats = reader->ReadBoolean();
    }

    void NPCGoods::WritePacket(BinaryWriter *writer)
    {
        writer->Write(List.size());

        for (int i = 0; i < List.size(); i++)
        {
            List[i]->Save(writer);
        }

        writer->Write(Rate);
        writer->Write(static_cast<unsigned char>(Type));

        writer->Write(HideAddedStats);
    }

    short NPCSell::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::NPCSell);
    }

    void NPCSell::ReadPacket(BinaryReader *reader)
    {
    }

    void NPCSell::WritePacket(BinaryWriter *writer)
    {
    }

    short NPCRepair::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::NPCRepair);
    }

    void NPCRepair::ReadPacket(BinaryReader *reader)
    {
        Rate = reader->ReadSingle();
    }

    void NPCRepair::WritePacket(BinaryWriter *writer)
    {
        writer->Write(Rate);
    }

    short NPCSRepair::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::NPCSRepair);
    }

    void NPCSRepair::ReadPacket(BinaryReader *reader)
    {
        Rate = reader->ReadSingle();
    }

    void NPCSRepair::WritePacket(BinaryWriter *writer)
    {
        writer->Write(Rate);
    }

    short NPCRefine::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::NPCRefine);
    }

    void NPCRefine::ReadPacket(BinaryReader *reader)
    {
        Rate = reader->ReadSingle();
        Refining = reader->ReadBoolean();
    }

    void NPCRefine::WritePacket(BinaryWriter *writer)
    {
        writer->Write(Rate);
        writer->Write(Refining);
    }

    short NPCCheckRefine::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::NPCCheckRefine);
    }

    void NPCCheckRefine::ReadPacket(BinaryReader *reader)
    {
    }

    void NPCCheckRefine::WritePacket(BinaryWriter *writer)
    {
    }

    short NPCCollectRefine::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::NPCCollectRefine);
    }

    void NPCCollectRefine::ReadPacket(BinaryReader *reader)
    {
        Success = reader->ReadBoolean();
    }

    void NPCCollectRefine::WritePacket(BinaryWriter *writer)
    {
        writer->Write(Success);
    }

    short NPCReplaceWedRing::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::NPCReplaceWedRing);
    }

    void NPCReplaceWedRing::ReadPacket(BinaryReader *reader)
    {
        Rate = reader->ReadSingle();
    }

    void NPCReplaceWedRing::WritePacket(BinaryWriter *writer)
    {
        writer->Write(Rate);
    }

    short NPCStorage::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::NPCStorage);
    }

    void NPCStorage::ReadPacket(BinaryReader *reader)
    {
    }

    void NPCStorage::WritePacket(BinaryWriter *writer)
    {
    }

    short SellItem::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::SellItem);
    }

    void SellItem::ReadPacket(BinaryReader *reader)
    {
        UniqueID = reader->ReadUInt64();
        Count = reader->ReadUInt16();
        Success = reader->ReadBoolean();
    }

    void SellItem::WritePacket(BinaryWriter *writer)
    {
        writer->Write(UniqueID);
        writer->Write(Count);
        writer->Write(Success);
    }

    short RepairItem::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::RepairItem);
    }

    void RepairItem::ReadPacket(BinaryReader *reader)
    {
        UniqueID = reader->ReadUInt64();
    }

    void RepairItem::WritePacket(BinaryWriter *writer)
    {
        writer->Write(UniqueID);
    }

    short ItemRepaired::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::ItemRepaired);
    }

    void ItemRepaired::ReadPacket(BinaryReader *reader)
    {
        UniqueID = reader->ReadUInt64();
        MaxDura = reader->ReadUInt16();
        CurrentDura = reader->ReadUInt16();
    }

    void ItemRepaired::WritePacket(BinaryWriter *writer)
    {
        writer->Write(UniqueID);
        writer->Write(MaxDura);
        writer->Write(CurrentDura);
    }

    short ItemSlotSizeChanged::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::ItemSlotSizeChanged);
    }

    void ItemSlotSizeChanged::ReadPacket(BinaryReader *reader)
    {
        UniqueID = reader->ReadUInt64();
        SlotSize = reader->ReadInt32();
    }

    void ItemSlotSizeChanged::WritePacket(BinaryWriter *writer)
    {
        writer->Write(UniqueID);
        writer->Write(SlotSize);
    }

    short NewMagic::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::NewMagic);
    }

    void NewMagic::ReadPacket(BinaryReader *reader)
    {
        Magic = new ClientMagic(reader);
    }

    void NewMagic::WritePacket(BinaryWriter *writer)
    {
        Magic->Save(writer);
    }

    short RemoveMagic::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::RemoveMagic);
    }

    void RemoveMagic::ReadPacket(BinaryReader *reader)
    {
        PlaceId = reader->ReadInt32();
    }

    void RemoveMagic::WritePacket(BinaryWriter *writer)
    {
        writer->Write(PlaceId);
    }

    short MagicLeveled::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::MagicLeveled);
    }

    void MagicLeveled::ReadPacket(BinaryReader *reader)
    {
        Spell = static_cast<Spell>(reader->ReadByte());
        Level = reader->ReadByte();
        Experience = reader->ReadUInt16();
    }

    void MagicLeveled::WritePacket(BinaryWriter *writer)
    {
        writer->Write(static_cast<unsigned char>(Spell));
        writer->Write(Level);
        writer->Write(Experience);
    }

    short Magic::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::Magic);
    }

    void Magic::ReadPacket(BinaryReader *reader)
    {
        Spell = static_cast<Spell>(reader->ReadByte());
        TargetID = reader->ReadUInt32();
        Target = new Point(reader->ReadInt32(), reader->ReadInt32());
        Cast = reader->ReadBoolean();
        Level = reader->ReadByte();

        auto count = reader->ReadInt32();
        SecondaryTargetIDs = std::vector<unsigned int>();
        for (int i = 0; i < count; i++)
        {
            SecondaryTargetIDs.push_back(reader->ReadUInt32());
        }
    }

    void Magic::WritePacket(BinaryWriter *writer)
    {
        writer->Write(static_cast<unsigned char>(Spell));
        writer->Write(TargetID);
        writer->Write(Target->X);
        writer->Write(Target->Y);
        writer->Write(Cast);
        writer->Write(Level);

        writer->Write(SecondaryTargetIDs.size());
        for (auto targetID : SecondaryTargetIDs)
        {
            writer->Write(targetID);
        }

    }

    short MagicDelay::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::MagicDelay);
    }

    void MagicDelay::ReadPacket(BinaryReader *reader)
    {
        Spell = static_cast<Spell>(reader->ReadByte());
        Delay = reader->ReadInt64();
    }

    void MagicDelay::WritePacket(BinaryWriter *writer)
    {
        writer->Write(static_cast<unsigned char>(Spell));
        writer->Write(Delay);
    }

    short MagicCast::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::MagicCast);
    }

    void MagicCast::ReadPacket(BinaryReader *reader)
    {
        Spell = static_cast<Spell>(reader->ReadByte());
    }

    void MagicCast::WritePacket(BinaryWriter *writer)
    {
        writer->Write(static_cast<unsigned char>(Spell));
    }

    short ObjectMagic::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::ObjectMagic);
    }

    void ObjectMagic::ReadPacket(BinaryReader *reader)
    {
        ObjectID = reader->ReadUInt32();
        Location = new Point(reader->ReadInt32(), reader->ReadInt32());
        Direction = static_cast<MirDirection>(reader->ReadByte());

        Spell = static_cast<Spell>(reader->ReadByte());
        TargetID = reader->ReadUInt32();

        Target = new Point(reader->ReadInt32(), reader->ReadInt32());
        Cast = reader->ReadBoolean();
        Level = reader->ReadByte();
        SelfBroadcast = reader->ReadBoolean();

        auto count = reader->ReadInt32();
        SecondaryTargetIDs = std::vector<unsigned int>();
        for (int i = 0; i < count; i++)
        {
            SecondaryTargetIDs.push_back(reader->ReadUInt32());
        }
    }

    void ObjectMagic::WritePacket(BinaryWriter *writer)
    {
        writer->Write(ObjectID);
        writer->Write(Location->X);
        writer->Write(Location->Y);
        writer->Write(static_cast<unsigned char>(Direction));

        writer->Write(static_cast<unsigned char>(Spell));
        writer->Write(TargetID);

        writer->Write(Target->X);
        writer->Write(Target->Y);
        writer->Write(Cast);
        writer->Write(Level);
        writer->Write(SelfBroadcast);

        writer->Write(SecondaryTargetIDs.size());
        for (auto targetID : SecondaryTargetIDs)
        {
            writer->Write(targetID);
        }
    }

    short ObjectEffect::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::ObjectEffect);
    }

    void ObjectEffect::ReadPacket(BinaryReader *reader)
    {
        ObjectID = reader->ReadUInt32();
        Effect = static_cast<SpellEffect>(reader->ReadByte());
        EffectType = reader->ReadUInt32();
        DelayTime = reader->ReadUInt32();
        Time = reader->ReadUInt32();
    }

    void ObjectEffect::WritePacket(BinaryWriter *writer)
    {
        writer->Write(ObjectID);
        writer->Write(static_cast<unsigned char>(Effect));
        writer->Write(EffectType);
        writer->Write(DelayTime);
        writer->Write(Time);
    }

    short ObjectProjectile::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::ObjectProjectile);
    }

    void ObjectProjectile::ReadPacket(BinaryReader *reader)
    {
        Spell = static_cast<Spell>(reader->ReadByte());
        Source = reader->ReadUInt32();
        Destination = reader->ReadUInt32();
    }

    void ObjectProjectile::WritePacket(BinaryWriter *writer)
    {
        writer->Write(static_cast<unsigned char>(Spell));
        writer->Write(Source);
        writer->Write(Destination);
    }

    short RangeAttack::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::RangeAttack);
    }

    void RangeAttack::ReadPacket(BinaryReader *reader)
    {
        TargetID = reader->ReadUInt32();
        Target = new Point(reader->ReadInt32(), reader->ReadInt32());
        Spell = static_cast<Spell>(reader->ReadByte());
    }

    void RangeAttack::WritePacket(BinaryWriter *writer)
    {
        writer->Write(TargetID);
        writer->Write(Target->X);
        writer->Write(Target->Y);
        writer->Write(static_cast<unsigned char>(Spell));
    }

    short Pushed::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::Pushed);
    }

    void Pushed::ReadPacket(BinaryReader *reader)
    {
        Location = new Point(reader->ReadInt32(), reader->ReadInt32());
        Direction = static_cast<MirDirection>(reader->ReadByte());
    }

    void Pushed::WritePacket(BinaryWriter *writer)
    {
        writer->Write(Location->X);
        writer->Write(Location->Y);
        writer->Write(static_cast<unsigned char>(Direction));
    }

    short ObjectPushed::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::ObjectPushed);
    }

    void ObjectPushed::ReadPacket(BinaryReader *reader)
    {
        ObjectID = reader->ReadUInt32();
        Location = new Point(reader->ReadInt32(), reader->ReadInt32());
        Direction = static_cast<MirDirection>(reader->ReadByte());
    }

    void ObjectPushed::WritePacket(BinaryWriter *writer)
    {
        writer->Write(ObjectID);
        writer->Write(Location->X);
        writer->Write(Location->Y);
        writer->Write(static_cast<unsigned char>(Direction));
    }

    short ObjectName::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::ObjectName);
    }

    void ObjectName::ReadPacket(BinaryReader *reader)
    {
        ObjectID = reader->ReadUInt32();
        Name = reader->ReadString();
    }

    void ObjectName::WritePacket(BinaryWriter *writer)
    {
        writer->Write(ObjectID);
        writer->Write(Name);
    }

    short UserStorage::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::UserStorage);
    }

    void UserStorage::ReadPacket(BinaryReader *reader)
    {
        if (!reader->ReadBoolean())
        {
            return;
        }

        Storage = std::vector<UserItem*>(reader->ReadInt32());
        for (int i = 0; i < Storage.size(); i++)
        {
            if (!reader->ReadBoolean())
            {
                continue;
            }
            Storage[i] = new UserItem(reader);
        }
    }

    void UserStorage::WritePacket(BinaryWriter *writer)
    {
        writer->Write(!Storage.empty());
        if (Storage.empty())
        {
            return;
        }

        writer->Write(Storage.size());
        for (int i = 0; i < Storage.size(); i++)
        {
            writer->Write(Storage[i] != nullptr);
            if (Storage[i] == nullptr)
            {
                continue;
            }

            Storage[i]->Save(writer);
        }
    }

    short SwitchGroup::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::SwitchGroup);
    }

    void SwitchGroup::ReadPacket(BinaryReader *reader)
    {
        AllowGroup = reader->ReadBoolean();
    }

    void SwitchGroup::WritePacket(BinaryWriter *writer)
    {
        writer->Write(AllowGroup);
    }

    short DeleteGroup::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::DeleteGroup);
    }

    void DeleteGroup::ReadPacket(BinaryReader *reader)
    {
    }

    void DeleteGroup::WritePacket(BinaryWriter *writer)
    {
    }

    short DeleteMember::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::DeleteMember);
    }

    void DeleteMember::ReadPacket(BinaryReader *reader)
    {
        Name = reader->ReadString();
    }

    void DeleteMember::WritePacket(BinaryWriter *writer)
    {
        writer->Write(Name);
    }

    short GroupInvite::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::GroupInvite);
    }

    void GroupInvite::ReadPacket(BinaryReader *reader)
    {
        Name = reader->ReadString();
    }

    void GroupInvite::WritePacket(BinaryWriter *writer)
    {
        writer->Write(Name);
    }

    short AddMember::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::AddMember);
    }

    void AddMember::ReadPacket(BinaryReader *reader)
    {
        Name = reader->ReadString();
    }

    void AddMember::WritePacket(BinaryWriter *writer)
    {
        writer->Write(Name);
    }

    short Revived::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::Revived);
    }

    void Revived::ReadPacket(BinaryReader *reader)
    {
    }

    void Revived::WritePacket(BinaryWriter *writer)
    {
    }

    short ObjectRevived::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::ObjectRevived);
    }

    void ObjectRevived::ReadPacket(BinaryReader *reader)
    {
        ObjectID = reader->ReadUInt32();
        Effect = reader->ReadBoolean();
    }

    void ObjectRevived::WritePacket(BinaryWriter *writer)
    {
        writer->Write(ObjectID);
        writer->Write(Effect);
    }

    short SpellToggle::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::SpellToggle);
    }

    void SpellToggle::ReadPacket(BinaryReader *reader)
    {
        Spell = static_cast<Spell>(reader->ReadByte());
        CanUse = reader->ReadBoolean();
    }

    void SpellToggle::WritePacket(BinaryWriter *writer)
    {
        writer->Write(static_cast<unsigned char>(Spell));
        writer->Write(CanUse);
    }

    short ObjectHealth::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::ObjectHealth);
    }

    void ObjectHealth::ReadPacket(BinaryReader *reader)
    {
        ObjectID = reader->ReadUInt32();
        Percent = reader->ReadByte();
        Expire = reader->ReadByte();
    }

    void ObjectHealth::WritePacket(BinaryWriter *writer)
    {
        writer->Write(ObjectID);
        writer->Write(Percent);
        writer->Write(Expire);
    }

    short MapEffect::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::MapEffect);
    }

    void MapEffect::ReadPacket(BinaryReader *reader)
    {
        Location = new Point(reader->ReadInt32(), reader->ReadInt32());
        Effect = static_cast<SpellEffect>(reader->ReadByte());
        Value = reader->ReadByte();
    }

    void MapEffect::WritePacket(BinaryWriter *writer)
    {
        writer->Write(Location->X);
        writer->Write(Location->Y);
        writer->Write(static_cast<unsigned char>(Effect));
        writer->Write(Value);
    }

    short ObjectRangeAttack::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::ObjectRangeAttack);
    }

    void ObjectRangeAttack::ReadPacket(BinaryReader *reader)
    {
        ObjectID = reader->ReadUInt32();
        Location = new Point(reader->ReadInt32(), reader->ReadInt32());
        Direction = static_cast<MirDirection>(reader->ReadByte());
        TargetID = reader->ReadUInt32();
        Target = new Point(reader->ReadInt32(), reader->ReadInt32());
        Type = reader->ReadByte();
        Spell = static_cast<Spell>(reader->ReadByte());
    }

    void ObjectRangeAttack::WritePacket(BinaryWriter *writer)
    {
        writer->Write(ObjectID);
        writer->Write(Location->X);
        writer->Write(Location->Y);
        writer->Write(static_cast<unsigned char>(Direction));
        writer->Write(TargetID);
        writer->Write(Target->X);
        writer->Write(Target->Y);
        writer->Write(Type);
        writer->Write(static_cast<unsigned char>(Spell));
    }

    short AddBuff::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::AddBuff);
    }

    void AddBuff::ReadPacket(BinaryReader *reader)
    {
        Buff = new ClientBuff(reader);
    }

    void AddBuff::WritePacket(BinaryWriter *writer)
    {
        Buff->Save(writer);
    }

    short RemoveBuff::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::RemoveBuff);
    }

    void RemoveBuff::ReadPacket(BinaryReader *reader)
    {
        Type = static_cast<BuffType>(reader->ReadByte());
        ObjectID = reader->ReadUInt32();
    }

    void RemoveBuff::WritePacket(BinaryWriter *writer)
    {
        writer->Write(static_cast<unsigned char>(Type));
        writer->Write(ObjectID);
    }

    short ObjectHidden::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::ObjectHidden);
    }

    void ObjectHidden::ReadPacket(BinaryReader *reader)
    {
        ObjectID = reader->ReadUInt32();
        Hidden = reader->ReadBoolean();
    }

    void ObjectHidden::WritePacket(BinaryWriter *writer)
    {
        writer->Write(ObjectID);
        writer->Write(Hidden);
    }

    short RefreshItem::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::RefreshItem);
    }

    void RefreshItem::ReadPacket(BinaryReader *reader)
    {
        Item = new UserItem(reader);
    }

    void RefreshItem::WritePacket(BinaryWriter *writer)
    {
        Item->Save(writer);
    }

    short ObjectSpell::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::ObjectSpell);
    }

    void ObjectSpell::ReadPacket(BinaryReader *reader)
    {
        ObjectID = reader->ReadUInt32();
        Location = new Point(reader->ReadInt32(), reader->ReadInt32());
        Spell = static_cast<Spell>(reader->ReadByte());
        Direction = static_cast<MirDirection>(reader->ReadByte());
        Param = reader->ReadBoolean();
    }

    void ObjectSpell::WritePacket(BinaryWriter *writer)
    {
        writer->Write(ObjectID);
        writer->Write(Location->X);
        writer->Write(Location->Y);
        writer->Write(static_cast<unsigned char>(Spell));
        writer->Write(static_cast<unsigned char>(Direction));
        writer->Write(Param);
    }

    short UserDash::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::UserDash);
    }

    void UserDash::ReadPacket(BinaryReader *reader)
    {
        Location = new Point(reader->ReadInt32(), reader->ReadInt32());
        Direction = static_cast<MirDirection>(reader->ReadByte());
    }

    void UserDash::WritePacket(BinaryWriter *writer)
    {
        writer->Write(Location->X);
        writer->Write(Location->Y);
        writer->Write(static_cast<unsigned char>(Direction));
    }

    short ObjectDash::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::ObjectDash);
    }

    void ObjectDash::ReadPacket(BinaryReader *reader)
    {
        ObjectID = reader->ReadUInt32();
        Location = new Point(reader->ReadInt32(), reader->ReadInt32());
        Direction = static_cast<MirDirection>(reader->ReadByte());
    }

    void ObjectDash::WritePacket(BinaryWriter *writer)
    {
        writer->Write(ObjectID);
        writer->Write(Location->X);
        writer->Write(Location->Y);
        writer->Write(static_cast<unsigned char>(Direction));
    }

    short UserDashFail::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::UserDashFail);
    }

    void UserDashFail::ReadPacket(BinaryReader *reader)
    {
        Location = new Point(reader->ReadInt32(), reader->ReadInt32());
        Direction = static_cast<MirDirection>(reader->ReadByte());
    }

    void UserDashFail::WritePacket(BinaryWriter *writer)
    {
        writer->Write(Location->X);
        writer->Write(Location->Y);
        writer->Write(static_cast<unsigned char>(Direction));
    }

    short ObjectDashFail::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::ObjectDashFail);
    }

    void ObjectDashFail::ReadPacket(BinaryReader *reader)
    {
        ObjectID = reader->ReadUInt32();
        Location = new Point(reader->ReadInt32(), reader->ReadInt32());
        Direction = static_cast<MirDirection>(reader->ReadByte());
    }

    void ObjectDashFail::WritePacket(BinaryWriter *writer)
    {
        writer->Write(ObjectID);
        writer->Write(Location->X);
        writer->Write(Location->Y);
        writer->Write(static_cast<unsigned char>(Direction));
    }

    short RemoveDelayedExplosion::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::RemoveDelayedExplosion);
    }

    void RemoveDelayedExplosion::ReadPacket(BinaryReader *reader)
    {
        ObjectID = reader->ReadUInt32();
    }

    void RemoveDelayedExplosion::WritePacket(BinaryWriter *writer)
    {
        writer->Write(ObjectID);
    }

    short NPCConsign::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::NPCConsign);
    }

    void NPCConsign::ReadPacket(BinaryReader *reader)
    {
    }

    void NPCConsign::WritePacket(BinaryWriter *writer)
    {
    }

    short NPCMarket::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::NPCMarket);
    }

    void NPCMarket::ReadPacket(BinaryReader *reader)
    {
        int count = reader->ReadInt32();

        for (int i = 0; i < count; i++)
        {
            ClientAuction tempVar(reader);
            Listings.push_back(&tempVar);
        }

        Pages = reader->ReadInt32();
        UserMode = reader->ReadBoolean();
    }

    void NPCMarket::WritePacket(BinaryWriter *writer)
    {
        writer->Write(Listings.size());

        for (int i = 0; i < Listings.size(); i++)
        {
            Listings[i]->Save(writer);
        }

        writer->Write(Pages);
        writer->Write(UserMode);
    }

    short NPCMarketPage::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::NPCMarketPage);
    }

    void NPCMarketPage::ReadPacket(BinaryReader *reader)
    {
        int count = reader->ReadInt32();

        for (int i = 0; i < count; i++)
        {
            ClientAuction tempVar(reader);
            Listings.push_back(&tempVar);
        }
    }

    void NPCMarketPage::WritePacket(BinaryWriter *writer)
    {
        writer->Write(Listings.size());

        for (int i = 0; i < Listings.size(); i++)
        {
            Listings[i]->Save(writer);
        }
    }

    short ConsignItem::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::ConsignItem);
    }

    void ConsignItem::ReadPacket(BinaryReader *reader)
    {
        UniqueID = reader->ReadUInt64();
        Success = reader->ReadBoolean();
    }

    void ConsignItem::WritePacket(BinaryWriter *writer)
    {
        writer->Write(UniqueID);
        writer->Write(Success);
    }

    short MarketFail::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::MarketFail);
    }

    void MarketFail::ReadPacket(BinaryReader *reader)
    {
        Reason = reader->ReadByte();
    }

    void MarketFail::WritePacket(BinaryWriter *writer)
    {
        writer->Write(Reason);
    }

    short MarketSuccess::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::MarketSuccess);
    }

    void MarketSuccess::ReadPacket(BinaryReader *reader)
    {
        Message = reader->ReadString();
    }

    void MarketSuccess::WritePacket(BinaryWriter *writer)
    {
        writer->Write(Message);
    }

    short ObjectSitDown::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::ObjectSitDown);
    }

    void ObjectSitDown::ReadPacket(BinaryReader *reader)
    {
        ObjectID = reader->ReadUInt32();
        Location = new Point(reader->ReadInt32(), reader->ReadInt32());
        Direction = static_cast<MirDirection>(reader->ReadByte());
        Sitting = reader->ReadBoolean();
    }

    void ObjectSitDown::WritePacket(BinaryWriter *writer)
    {
        writer->Write(ObjectID);
        writer->Write(Location->X);
        writer->Write(Location->Y);
        writer->Write(static_cast<unsigned char>(Direction));
        writer->Write(Sitting);
    }

    short InTrapRock::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::InTrapRock);
    }

    void InTrapRock::ReadPacket(BinaryReader *reader)
    {
        Trapped = reader->ReadBoolean();
    }

    void InTrapRock::WritePacket(BinaryWriter *writer)
    {
        writer->Write(Trapped);
    }

    short BaseStatsInfo::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::BaseStatsInfo);
    }

    void BaseStatsInfo::ReadPacket(BinaryReader *reader)
    {
        Stats = new BaseStats(reader);
    }

    void BaseStatsInfo::WritePacket(BinaryWriter *writer)
    {
        Stats->Save(writer);
    }

    short UserName::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::UserName);
    }

    void UserName::ReadPacket(BinaryReader *reader)
    {
        Id = reader->ReadUInt32();
        Name = reader->ReadString();
    }

    void UserName::WritePacket(BinaryWriter *writer)
    {
        writer->Write(Id);
        writer->Write(Name);
    }

    short ChatItemStats::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::ChatItemStats);
    }

    void ChatItemStats::ReadPacket(BinaryReader *reader)
    {
        ChatItemId = reader->ReadUInt64();
        Stats = new UserItem(reader);
    }

    void ChatItemStats::WritePacket(BinaryWriter *writer)
    {
        writer->Write(ChatItemId);
        if (Stats != nullptr)
        {
            Stats->Save(writer);
        }
    }

    short GuildNoticeChange::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::GuildNoticeChange);
    }

    void GuildNoticeChange::ReadPacket(BinaryReader *reader)
    {
        update = reader->ReadInt32();
        for (int i = 0; i < update; i++)
        {
            notice.push_back(reader->ReadString());
        }
    }

    void GuildNoticeChange::WritePacket(BinaryWriter *writer)
    {
        if (update < 0)
        {
            writer->Write(update);
            return;
        }
        writer->Write(notice.size());
        for (int i = 0; i < notice.size(); i++)
        {
            writer->Write(notice[i]);
        }
    }

    short GuildMemberChange::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::GuildMemberChange);
    }

    void GuildMemberChange::ReadPacket(BinaryReader *reader)
    {
        Name = reader->ReadString();
        RankIndex = reader->ReadByte();
        Status = reader->ReadByte();
        if (Status > 5)
        {
            int rankcount = reader->ReadInt32();
            for (int i = 0; i < rankcount; i++)
            {
                GuildRank tempVar(reader);
                Ranks.push_back(&tempVar);
            }
        }
    }

    void GuildMemberChange::WritePacket(BinaryWriter *writer)
    {
        writer->Write(Name);
        writer->Write(RankIndex);
        writer->Write(Status);
        if (Status > 5)
        {
            writer->Write(Ranks.size());
            for (int i = 0; i < Ranks.size(); i++)
            {
                Ranks[i]->Save(writer);
            }
        }
    }

    short GuildStatus::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::GuildStatus);
    }

    void GuildStatus::ReadPacket(BinaryReader *reader)
    {
        GuildName = reader->ReadString();
        GuildRankName = reader->ReadString();
        Level = reader->ReadByte();
        Experience = reader->ReadInt64();
        MaxExperience = reader->ReadInt64();
        Gold = reader->ReadUInt32();
        SparePoints = reader->ReadByte();
        MemberCount = reader->ReadInt32();
        MaxMembers = reader->ReadInt32();
        Voting = reader->ReadBoolean();
        ItemCount = reader->ReadByte();
        BuffCount = reader->ReadByte();
        MyOptions = static_cast<GuildRankOptions>(reader->ReadByte());
        MyRankId = reader->ReadInt32();
    }

    void GuildStatus::WritePacket(BinaryWriter *writer)
    {
        writer->Write(GuildName);
        writer->Write(GuildRankName);
        writer->Write(Level);
        writer->Write(Experience);
        writer->Write(MaxExperience);
        writer->Write(Gold);
        writer->Write(SparePoints);
        writer->Write(MemberCount);
        writer->Write(MaxMembers);
        writer->Write(Voting);
        writer->Write(ItemCount);
        writer->Write(BuffCount);
        writer->Write(static_cast<unsigned char>(MyOptions));
        writer->Write(MyRankId);
    }

    short GuildInvite::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::GuildInvite);
    }

    void GuildInvite::ReadPacket(BinaryReader *reader)
    {
        Name = reader->ReadString();
    }

    void GuildInvite::WritePacket(BinaryWriter *writer)
    {
        writer->Write(Name);
    }

    short GuildExpGain::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::GuildExpGain);
    }

    void GuildExpGain::ReadPacket(BinaryReader *reader)
    {
        Amount = reader->ReadUInt32();
    }

    void GuildExpGain::WritePacket(BinaryWriter *writer)
    {
        writer->Write(Amount);
    }

    short GuildNameRequest::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::GuildNameRequest);
    }

    void GuildNameRequest::ReadPacket(BinaryReader *reader)
    {
    }

    void GuildNameRequest::WritePacket(BinaryWriter *writer)
    {
    }

    short GuildStorageGoldChange::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::GuildStorageGoldChange);
    }

    void GuildStorageGoldChange::ReadPacket(BinaryReader *reader)
    {
        Amount = reader->ReadUInt32();
        Type = reader->ReadByte();
        Name = reader->ReadString();
    }

    void GuildStorageGoldChange::WritePacket(BinaryWriter *writer)
    {
        writer->Write(Amount);
        writer->Write(Type);
        writer->Write(Name);
    }

    short GuildStorageItemChange::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::GuildStorageItemChange);
    }

    void GuildStorageItemChange::ReadPacket(BinaryReader *reader)
    {
        Type = reader->ReadByte();
        To = reader->ReadInt32();
        From = reader->ReadInt32();
        User = reader->ReadInt32();
        if (!reader->ReadBoolean())
        {
            return;
        }
        Item = new GuildStorageItem();
        Item->UserId = reader->ReadInt64();
        Item->Item = new UserItem(reader);
    }

    void GuildStorageItemChange::WritePacket(BinaryWriter *writer)
    {
        writer->Write(Type);
        writer->Write(To);
        writer->Write(From);
        writer->Write(User);
        writer->Write(Item != nullptr);
        if (Item == nullptr)
        {
            return;
        }
        writer->Write(Item->UserId);
        Item->Item->Save(writer);
    }

    short GuildStorageList::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::GuildStorageList);
    }

    void GuildStorageList::ReadPacket(BinaryReader *reader)
    {
        Items = std::vector<GuildStorageItem*>(reader->ReadInt32());
        for (int i = 0; i < Items.size(); i++)
        {
            if (reader->ReadBoolean() == true)
            {
                Items[i] = new GuildStorageItem(reader);
            }
        }
    }

    void GuildStorageList::WritePacket(BinaryWriter *writer)
    {
        writer->Write(Items.size());
        for (int i = 0; i < Items.size(); i++)
        {
            writer->Write(Items[i] != nullptr);
            if (Items[i] != nullptr)
            {
                Items[i]->Save(writer);
            }
        }
    }

    short GuildRequestWar::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::GuildRequestWar);
    }

    void GuildRequestWar::ReadPacket(BinaryReader *reader)
    {
    }

    void GuildRequestWar::WritePacket(BinaryWriter *writer)
    {
    }

    short DefaultNPC::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::DefaultNPC);
    }

    void DefaultNPC::ReadPacket(BinaryReader *reader)
    {
        ObjectID = reader->ReadUInt32();
    }

    void DefaultNPC::WritePacket(BinaryWriter *writer)
    {
        writer->Write(ObjectID);
    }

    short NPCUpdate::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::NPCUpdate);
    }

    void NPCUpdate::ReadPacket(BinaryReader *reader)
    {
        NPCID = reader->ReadUInt32();
    }

    void NPCUpdate::WritePacket(BinaryWriter *writer)
    {
        writer->Write(NPCID);
    }

    short NPCImageUpdate::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::NPCImageUpdate);
    }

    void NPCImageUpdate::ReadPacket(BinaryReader *reader)
    {
        ObjectID = reader->ReadInt64();
        Image = reader->ReadUInt16();
        Colour = Color::FromArgb(reader->ReadInt32());
    }

    void NPCImageUpdate::WritePacket(BinaryWriter *writer)
    {
        writer->Write(ObjectID);
        writer->Write(Image);
        writer->Write(Colour->ToArgb());
    }

    short MountUpdate::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::MountUpdate);
    }

    void MountUpdate::ReadPacket(BinaryReader *reader)
    {
        ObjectID = reader->ReadInt64();
        MountType = reader->ReadInt16();
        RidingMount = reader->ReadBoolean();
    }

    void MountUpdate::WritePacket(BinaryWriter *writer)
    {
        writer->Write(ObjectID);
        writer->Write(MountType);
        writer->Write(RidingMount);
    }

    short TransformUpdate::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::TransformUpdate);
    }

    void TransformUpdate::ReadPacket(BinaryReader *reader)
    {
        ObjectID = reader->ReadInt64();
        TransformType = reader->ReadInt16();
    }

    void TransformUpdate::WritePacket(BinaryWriter *writer)
    {
        writer->Write(ObjectID);
        writer->Write(TransformType);
    }

    short EquipSlotItem::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::EquipSlotItem);
    }

    void EquipSlotItem::ReadPacket(BinaryReader *reader)
    {
        Grid = static_cast<MirGridType>(reader->ReadByte());
        UniqueID = reader->ReadUInt64();
        To = reader->ReadInt32();
        GridTo = static_cast<MirGridType>(reader->ReadByte());
        Success = reader->ReadBoolean();
    }

    void EquipSlotItem::WritePacket(BinaryWriter *writer)
    {
        writer->Write(static_cast<unsigned char>(Grid));
        writer->Write(UniqueID);
        writer->Write(To);
        writer->Write(static_cast<unsigned char>(GridTo));
        writer->Write(Success);
    }

    short FishingUpdate::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::FishingUpdate);
    }

    void FishingUpdate::ReadPacket(BinaryReader *reader)
    {
        ObjectID = reader->ReadInt64();
        Fishing = reader->ReadBoolean();
        ProgressPercent = reader->ReadInt32();
        ChancePercent = reader->ReadInt32();
        FishingPoint = new Point(reader->ReadInt32(), reader->ReadInt32());
        FoundFish = reader->ReadBoolean();
    }

    void FishingUpdate::WritePacket(BinaryWriter *writer)
    {
        writer->Write(ObjectID);
        writer->Write(Fishing);
        writer->Write(ProgressPercent);
        writer->Write(ChancePercent);
        writer->Write(FishingPoint->X);
        writer->Write(FishingPoint->Y);
        writer->Write(FoundFish);
    }

    short ChangeQuest::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::ChangeQuest);
    }

    void ChangeQuest::ReadPacket(BinaryReader *reader)
    {
        Quest = new ClientQuestProgress(reader);
        QuestState = static_cast<QuestState>(reader->ReadByte());
        TrackQuest = reader->ReadBoolean();
    }

    void ChangeQuest::WritePacket(BinaryWriter *writer)
    {
        Quest->Save(writer);
        writer->Write(static_cast<unsigned char>(QuestState));
        writer->Write(TrackQuest);
    }

    short CompleteQuest::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::CompleteQuest);
    }

    void CompleteQuest::ReadPacket(BinaryReader *reader)
    {
        int count = reader->ReadInt32();
        for (auto i = 0; i < count; i++)
        {
            CompletedQuests.push_back(reader->ReadInt32());
        }
    }

    void CompleteQuest::WritePacket(BinaryWriter *writer)
    {
        writer->Write(CompletedQuests.size());
        for (auto q : CompletedQuests)
        {
            writer->Write(q);
        }
    }

    short ShareQuest::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::ShareQuest);
    }

    void ShareQuest::ReadPacket(BinaryReader *reader)
    {
        QuestIndex = reader->ReadInt32();
        SharerName = reader->ReadString();
    }

    void ShareQuest::WritePacket(BinaryWriter *writer)
    {
        writer->Write(QuestIndex);
        writer->Write(SharerName);
    }

    short NewQuestInfo::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::NewQuestInfo);
    }

    void NewQuestInfo::ReadPacket(BinaryReader *reader)
    {
        Info = new ClientQuestInfo(reader);
    }

    void NewQuestInfo::WritePacket(BinaryWriter *writer)
    {
        Info->Save(writer);
    }

    short GainedQuestItem::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::GainedQuestItem);
    }

    void GainedQuestItem::ReadPacket(BinaryReader *reader)
    {
        Item = new UserItem(reader);
    }

    void GainedQuestItem::WritePacket(BinaryWriter *writer)
    {
        Item->Save(writer);
    }

    short DeleteQuestItem::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::DeleteQuestItem);
    }

    void DeleteQuestItem::ReadPacket(BinaryReader *reader)
    {
        UniqueID = reader->ReadUInt64();
        Count = reader->ReadUInt16();
    }

    void DeleteQuestItem::WritePacket(BinaryWriter *writer)
    {
        writer->Write(UniqueID);
        writer->Write(Count);
    }

    short GameShopInfo::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::GameShopInfo);
    }

    void GameShopInfo::ReadPacket(BinaryReader *reader)
    {
        Item = new GameShopItem(reader, true);
        StockLevel = reader->ReadInt32();
    }

    void GameShopInfo::WritePacket(BinaryWriter *writer)
    {
        Item->Save(writer, true);
        writer->Write(StockLevel);
    }

    short GameShopStock::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::GameShopStock);
    }

    void GameShopStock::ReadPacket(BinaryReader *reader)
    {
        GIndex = reader->ReadInt32();
        StockLevel = reader->ReadInt32();
    }

    void GameShopStock::WritePacket(BinaryWriter *writer)
    {
        writer->Write(GIndex);
        writer->Write(StockLevel);
    }

    short CancelReincarnation::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::CancelReincarnation);
    }

    void CancelReincarnation::ReadPacket(BinaryReader *reader)
    {
    }

    void CancelReincarnation::WritePacket(BinaryWriter *writer)
    {
    }

    short RequestReincarnation::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::RequestReincarnation);
    }

    void RequestReincarnation::ReadPacket(BinaryReader *reader)
    {
    }

    void RequestReincarnation::WritePacket(BinaryWriter *writer)
    {
    }

    short UserBackStep::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::UserBackStep);
    }

    void UserBackStep::ReadPacket(BinaryReader *reader)
    {
        Location = new Point(reader->ReadInt32(), reader->ReadInt32());
        Direction = static_cast<MirDirection>(reader->ReadByte());
    }

    void UserBackStep::WritePacket(BinaryWriter *writer)
    {
        writer->Write(Location->X);
        writer->Write(Location->Y);
        writer->Write(static_cast<unsigned char>(Direction));
    }

    short ObjectBackStep::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::ObjectBackStep);
    }

    void ObjectBackStep::ReadPacket(BinaryReader *reader)
    {
        ObjectID = reader->ReadUInt32();
        Location = new Point(reader->ReadInt32(), reader->ReadInt32());
        Direction = static_cast<MirDirection>(reader->ReadByte());
        Distance = reader->ReadInt16();
    }

    void ObjectBackStep::WritePacket(BinaryWriter *writer)
    {
        writer->Write(ObjectID);
        writer->Write(Location->X);
        writer->Write(Location->Y);
        writer->Write(static_cast<unsigned char>(Direction));
        writer->Write(Distance);
    }

    short UserDashAttack::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::UserDashAttack);
    }

    void UserDashAttack::ReadPacket(BinaryReader *reader)
    {
        Location = new Point(reader->ReadInt32(), reader->ReadInt32());
        Direction = static_cast<MirDirection>(reader->ReadByte());
    }

    void UserDashAttack::WritePacket(BinaryWriter *writer)
    {
        writer->Write(Location->X);
        writer->Write(Location->Y);
        writer->Write(static_cast<unsigned char>(Direction));
    }

    short ObjectDashAttack::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::ObjectDashAttack);
    }

    void ObjectDashAttack::ReadPacket(BinaryReader *reader)
    {
        ObjectID = reader->ReadUInt32();
        Location = new Point(reader->ReadInt32(), reader->ReadInt32());
        Direction = static_cast<MirDirection>(reader->ReadByte());
        Distance = reader->ReadInt16();
    }

    void ObjectDashAttack::WritePacket(BinaryWriter *writer)
    {
        writer->Write(ObjectID);
        writer->Write(Location->X);
        writer->Write(Location->Y);
        writer->Write(static_cast<unsigned char>(Direction));
        writer->Write(Distance);
    }

    short UserAttackMove::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::UserAttackMove);
    }

    void UserAttackMove::ReadPacket(BinaryReader *reader)
    {
        Location = new Point(reader->ReadInt32(), reader->ReadInt32());
        Direction = static_cast<MirDirection>(reader->ReadByte());
    }

    void UserAttackMove::WritePacket(BinaryWriter *writer)
    {
        writer->Write(Location->X);
        writer->Write(Location->Y);
        writer->Write(static_cast<unsigned char>(Direction));
    }

    short CombineItem::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::CombineItem);
    }

    void CombineItem::ReadPacket(BinaryReader *reader)
    {
        IDFrom = reader->ReadUInt64();
        IDTo = reader->ReadUInt64();
        Success = reader->ReadBoolean();
        Destroy = reader->ReadBoolean();
    }

    void CombineItem::WritePacket(BinaryWriter *writer)
    {
        writer->Write(IDFrom);
        writer->Write(IDTo);
        writer->Write(Success);
        writer->Write(Destroy);
    }

    short ItemUpgraded::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::ItemUpgraded);
    }

    void ItemUpgraded::ReadPacket(BinaryReader *reader)
    {
        Item = new UserItem(reader);
    }

    void ItemUpgraded::WritePacket(BinaryWriter *writer)
    {
        Item->Save(writer);
    }

    short SetConcentration::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::SetConcentration);
    }

    void SetConcentration::ReadPacket(BinaryReader *reader)
    {
        ObjectID = reader->ReadUInt32();
        Enabled = reader->ReadBoolean();
        Interrupted = reader->ReadBoolean();
    }

    void SetConcentration::WritePacket(BinaryWriter *writer)
    {
        writer->Write(ObjectID);
        writer->Write(Enabled);
        writer->Write(Interrupted);
    }

    short SetElemental::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::SetElemental);
    }

    void SetElemental::ReadPacket(BinaryReader *reader)
    {
        ObjectID = reader->ReadUInt32();
        Enabled = reader->ReadBoolean();
        Casted = reader->ReadBoolean();
        Value = reader->ReadUInt32();
        ElementType = reader->ReadUInt32();
        ExpLast = reader->ReadUInt32();
    }

    void SetElemental::WritePacket(BinaryWriter *writer)
    {
        writer->Write(ObjectID);
        writer->Write(Enabled);
        writer->Write(Casted);
        writer->Write(Value);
        writer->Write(ElementType);
        writer->Write(ExpLast);
    }

    short ObjectDeco::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::ObjectDeco);
    }

    void ObjectDeco::ReadPacket(BinaryReader *reader)
    {
        ObjectID = reader->ReadUInt32();
        Location = new Point(reader->ReadInt32(), reader->ReadInt32());
        Image = reader->ReadInt32();
    }

    void ObjectDeco::WritePacket(BinaryWriter *writer)
    {
        writer->Write(ObjectID);
        writer->Write(Location->X);
        writer->Write(Location->Y);
        writer->Write(Image);
    }

    short ObjectSneaking::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::ObjectSneaking);
    }

    void ObjectSneaking::ReadPacket(BinaryReader *reader)
    {
        ObjectID = reader->ReadUInt32();
        SneakingActive = reader->ReadBoolean();
    }

    void ObjectSneaking::WritePacket(BinaryWriter *writer)
    {
        writer->Write(ObjectID);
        writer->Write(SneakingActive);
    }

    short ObjectLevelEffects::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::ObjectLevelEffects);
    }

    void ObjectLevelEffects::ReadPacket(BinaryReader *reader)
    {
        ObjectID = reader->ReadUInt32();
        LevelEffects = static_cast<LevelEffects>(reader->ReadByte());
    }

    void ObjectLevelEffects::WritePacket(BinaryWriter *writer)
    {
        writer->Write(ObjectID);
        writer->Write(static_cast<unsigned char>(LevelEffects));
    }

    short SetBindingShot::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::SetBindingShot);
    }

    void SetBindingShot::ReadPacket(BinaryReader *reader)
    {
        ObjectID = reader->ReadUInt32();
        Enabled = reader->ReadBoolean();
        Value = reader->ReadInt64();
    }

    void SetBindingShot::WritePacket(BinaryWriter *writer)
    {
        writer->Write(ObjectID);
        writer->Write(Enabled);
        writer->Write(Value);
    }

    short SendOutputMessage::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::SendOutputMessage);
    }

    void SendOutputMessage::ReadPacket(BinaryReader *reader)
    {
        Message = reader->ReadString();
        Type = static_cast<OutputMessageType>(reader->ReadByte());
    }

    void SendOutputMessage::WritePacket(BinaryWriter *writer)
    {
        writer->Write(Message);
        writer->Write(static_cast<unsigned char>(Type));
    }

    short NPCAwakening::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::NPCAwakening);
    }

    void NPCAwakening::ReadPacket(BinaryReader *reader)
    {
    }

    void NPCAwakening::WritePacket(BinaryWriter *writer)
    {
    }

    short NPCDisassemble::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::NPCDisassemble);
    }

    void NPCDisassemble::ReadPacket(BinaryReader *reader)
    {
    }

    void NPCDisassemble::WritePacket(BinaryWriter *writer)
    {
    }

    short NPCDowngrade::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::NPCDowngrade);
    }

    void NPCDowngrade::ReadPacket(BinaryReader *reader)
    {
    }

    void NPCDowngrade::WritePacket(BinaryWriter *writer)
    {
    }

    short NPCReset::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::NPCReset);
    }

    void NPCReset::ReadPacket(BinaryReader *reader)
    {
    }

    void NPCReset::WritePacket(BinaryWriter *writer)
    {
    }

    short AwakeningNeedMaterials::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::AwakeningNeedMaterials);
    }

    void AwakeningNeedMaterials::ReadPacket(BinaryReader *reader)
    {
        if (!reader->ReadBoolean())
        {
            return;
        }

        int count = reader->ReadInt32();
        Materials = std::vector<ItemInfo*>(count);
        MaterialsCount = std::vector<unsigned char>(count);

        for (int i = 0; i < Materials.size(); i++)
        {
            if (!reader->ReadBoolean())
            {
                continue;
            }
            Materials[i] = new ItemInfo(reader);
            MaterialsCount[i] = reader->ReadByte();
        }
    }

    void AwakeningNeedMaterials::WritePacket(BinaryWriter *writer)
    {
        writer->Write(!Materials.empty());
        if (Materials.empty())
        {
            return;
        }

        writer->Write(Materials.size());
        for (int i = 0; i < Materials.size(); i++)
        {
            writer->Write(Materials[i] != nullptr);
            if (Materials[i] == nullptr)
            {
                continue;
            }

            Materials[i]->Save(writer);
            writer->Write(MaterialsCount[i]);
        }
    }

    short AwakeningLockedItem::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::AwakeningLockedItem);
    }

    void AwakeningLockedItem::ReadPacket(BinaryReader *reader)
    {
        UniqueID = reader->ReadUInt64();
        Locked = reader->ReadBoolean();
    }

    void AwakeningLockedItem::WritePacket(BinaryWriter *writer)
    {
        writer->Write(UniqueID);
        writer->Write(Locked);
    }

    short Awakening::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::Awakening);
    }

    void Awakening::ReadPacket(BinaryReader *reader)
    {
        result = reader->ReadInt32();
        removeID = reader->ReadInt64();
    }

    void Awakening::WritePacket(BinaryWriter *writer)
    {
        writer->Write(result);
        writer->Write(removeID);
    }

    short ReceiveMail::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::ReceiveMail);
    }

    void ReceiveMail::ReadPacket(BinaryReader *reader)
    {
        int count = reader->ReadInt32();

        for (int i = 0; i < count; i++)
        {
            ClientMail tempVar(reader);
            Mail.push_back(&tempVar);
        }
    }

    void ReceiveMail::WritePacket(BinaryWriter *writer)
    {
        writer->Write(Mail.size());

        for (int i = 0; i < Mail.size(); i++)
        {
            Mail[i]->Save(writer);
        }
    }

    short MailLockedItem::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::MailLockedItem);
    }

    void MailLockedItem::ReadPacket(BinaryReader *reader)
    {
        UniqueID = reader->ReadUInt64();
        Locked = reader->ReadBoolean();
    }

    void MailLockedItem::WritePacket(BinaryWriter *writer)
    {
        writer->Write(UniqueID);
        writer->Write(Locked);
    }

    short MailSent::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::MailSent);
    }

    void MailSent::ReadPacket(BinaryReader *reader)
    {
        Result = reader->ReadSByte();
    }

    void MailSent::WritePacket(BinaryWriter *writer)
    {
        writer->Write(Result);
    }

    short MailSendRequest::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::MailSendRequest);
    }

    void MailSendRequest::ReadPacket(BinaryReader *reader)
    {
    }

    void MailSendRequest::WritePacket(BinaryWriter *writer)
    {
    }

    short ParcelCollected::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::ParcelCollected);
    }

    void ParcelCollected::ReadPacket(BinaryReader *reader)
    {
        Result = reader->ReadSByte();
    }

    void ParcelCollected::WritePacket(BinaryWriter *writer)
    {
        writer->Write(Result);
    }

    short MailCost::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::MailCost);
    }

    void MailCost::ReadPacket(BinaryReader *reader)
    {
        Cost = reader->ReadUInt32();
    }

    void MailCost::WritePacket(BinaryWriter *writer)
    {
        writer->Write(Cost);
    }

    short ResizeInventory::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::ResizeInventory);
    }

    void ResizeInventory::ReadPacket(BinaryReader *reader)
    {
        Size = reader->ReadInt32();
    }

    void ResizeInventory::WritePacket(BinaryWriter *writer)
    {
        writer->Write(Size);
    }

    short ResizeStorage::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::ResizeStorage);
    }

    void ResizeStorage::ReadPacket(BinaryReader *reader)
    {
        Size = reader->ReadInt32();
        HasExpandedStorage = reader->ReadBoolean();
        ExpiryTime = DateTime::FromBinary(reader->ReadInt64());
    }

    void ResizeStorage::WritePacket(BinaryWriter *writer)
    {
        writer->Write(Size);
        writer->Write(HasExpandedStorage);
        writer->Write(ExpiryTime.ToBinary());
    }

    short NewIntelligentCreature::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::NewIntelligentCreature);
    }

    void NewIntelligentCreature::ReadPacket(BinaryReader *reader)
    {
        Creature = new ClientIntelligentCreature(reader);
    }

    void NewIntelligentCreature::WritePacket(BinaryWriter *writer)
    {
        Creature->Save(writer);
    }

    short UpdateIntelligentCreatureList::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::UpdateIntelligentCreatureList);
    }

    void UpdateIntelligentCreatureList::ReadPacket(BinaryReader *reader)
    {
        int count = reader->ReadInt32();
        for (int i = 0; i < count; i++)
        {
            ClientIntelligentCreature tempVar(reader);
            CreatureList.push_back(&tempVar);
        }
        CreatureSummoned = reader->ReadBoolean();
        SummonedCreatureType = static_cast<IntelligentCreatureType>(reader->ReadByte());
        PearlCount = reader->ReadInt32();
    }

    void UpdateIntelligentCreatureList::WritePacket(BinaryWriter *writer)
    {
        writer->Write(CreatureList.size());
        for (int i = 0; i < CreatureList.size(); i++)
        {
            CreatureList[i]->Save(writer);
        }
        writer->Write(CreatureSummoned);
        writer->Write(static_cast<unsigned char>(SummonedCreatureType));
        writer->Write(PearlCount);
    }

    short IntelligentCreatureEnableRename::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::IntelligentCreatureEnableRename);
    }

    void IntelligentCreatureEnableRename::ReadPacket(BinaryReader *reader)
    {
    }

    void IntelligentCreatureEnableRename::WritePacket(BinaryWriter *writer)
    {
    }

    short IntelligentCreaturePickup::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::IntelligentCreaturePickup);
    }

    void IntelligentCreaturePickup::ReadPacket(BinaryReader *reader)
    {
        ObjectID = reader->ReadUInt32();
    }

    void IntelligentCreaturePickup::WritePacket(BinaryWriter *writer)
    {
        writer->Write(ObjectID);
    }

    short NPCPearlGoods::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::NPCPearlGoods);
    }

    void NPCPearlGoods::ReadPacket(BinaryReader *reader)
    {
        int count = reader->ReadInt32();

        for (int i = 0; i < count; i++)
        {
            UserItem tempVar(reader);
            List.push_back(&tempVar);
        }

        Rate = reader->ReadSingle();

        Type = static_cast<PanelType>(reader->ReadByte());
    }

    void NPCPearlGoods::WritePacket(BinaryWriter *writer)
    {
        writer->Write(List.size());

        for (int i = 0; i < List.size(); i++)
        {
            List[i]->Save(writer);
        }

        writer->Write(Rate);
        writer->Write(static_cast<unsigned char>(Type));
    }

    short FriendUpdate::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::FriendUpdate);
    }

    void FriendUpdate::ReadPacket(BinaryReader *reader)
    {
        int count = reader->ReadInt32();

        for (int i = 0; i < count; i++)
        {
            ClientFriend tempVar(reader);
            Friends.push_back(&tempVar);
        }
    }

    void FriendUpdate::WritePacket(BinaryWriter *writer)
    {
        writer->Write(Friends.size());

        for (int i = 0; i < Friends.size(); i++)
        {
            Friends[i]->Save(writer);
        }
    }

    short GuildBuffList::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::GuildBuffList);
    }

    void GuildBuffList::ReadPacket(BinaryReader *reader)
    {
        Remove = reader->ReadByte();
        int count = reader->ReadInt32();
        for (int i = 0; i < count; i++)
        {
            GuildBuff tempVar(reader);
            ActiveBuffs.push_back(&tempVar);
        }
        count = reader->ReadInt32();
        for (int i = 0; i < count; i++)
        {
            GuildBuffInfo tempVar2(reader);
            GuildBuffs.push_back(&tempVar2);
        }
    }

    void GuildBuffList::WritePacket(BinaryWriter *writer)
    {
        writer->Write(Remove);
        writer->Write(ActiveBuffs.size());
        for (int i = 0; i < ActiveBuffs.size(); i++)
        {
            ActiveBuffs[i]->Save(writer);
        }
        writer->Write(GuildBuffs.size());
        for (int i = 0; i < GuildBuffs.size(); i++)
        {
            GuildBuffs[i]->Save(writer);
        }
    }

    short LoverUpdate::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::LoverUpdate);
    }

    void LoverUpdate::ReadPacket(BinaryReader *reader)
    {
        Name = reader->ReadString();
        Date = DateTime::FromBinary(reader->ReadInt64());
        MapName = reader->ReadString();
        MarriedDays = reader->ReadInt16();
    }

    void LoverUpdate::WritePacket(BinaryWriter *writer)
    {
        writer->Write(Name);
        writer->Write(Date.ToBinary());
        writer->Write(MapName);
        writer->Write(MarriedDays);
    }

    short MentorUpdate::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::MentorUpdate);
    }

    void MentorUpdate::ReadPacket(BinaryReader *reader)
    {
        Name = reader->ReadString();
        Level = reader->ReadUInt16();
        Online = reader->ReadBoolean();
        MenteeEXP = reader->ReadInt64();
    }

    void MentorUpdate::WritePacket(BinaryWriter *writer)
    {
        writer->Write(Name);
        writer->Write(Level);
        writer->Write(Online);
        writer->Write(MenteeEXP);
    }

    short NPCRequestInput::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::NPCRequestInput);
    }

    void NPCRequestInput::ReadPacket(BinaryReader *reader)
    {
        NPCID = reader->ReadUInt32();
        PageName = reader->ReadString();
    }

    void NPCRequestInput::WritePacket(BinaryWriter *writer)
    {
        writer->Write(NPCID);
        writer->Write(PageName);
    }

    short Rankings::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::Rankings);
    }

    void Rankings::ReadPacket(BinaryReader *reader)
    {
        RankType = reader->ReadByte();
        MyRank = reader->ReadInt32();
        int count = reader->ReadInt32();
        for (int i = 0; i < count; i++)
        {
            RankCharacterInfo tempVar(reader);
            Listings.push_back(&tempVar);
        }
    }

    void Rankings::WritePacket(BinaryWriter *writer)
    {
        writer->Write(RankType);
        writer->Write(MyRank);
        writer->Write(Listings.size());
        for (int i = 0; i < Listings.size(); i++)
        {
            Listings[i]->Save(writer);
        }
    }

    short Opendoor::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::Opendoor);
    }

    void Opendoor::ReadPacket(BinaryReader *reader)
    {
        DoorIndex = reader->ReadByte();
        Close = reader->ReadBoolean();
    }

    void Opendoor::WritePacket(BinaryWriter *writer)
    {
        writer->Write(DoorIndex);
        writer->Write(Close);
    }

    short GetRentedItems::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::GetRentedItems);
    }

    void GetRentedItems::ReadPacket(BinaryReader *reader)
    {
        auto count = reader->ReadInt32();

        for (auto i = 0; i < count; i++)
        {
            ItemRentalInformation tempVar(reader);
            RentedItems.push_back(&tempVar);
        }
    }

    void GetRentedItems::WritePacket(BinaryWriter *writer)
    {
        writer->Write(RentedItems.size());

        for (auto rentedItemInformation : RentedItems)
        {
            rentedItemInformation->Save(writer);
        }
    }

    short ItemRentalRequest::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::ItemRentalRequest);
    }

    void ItemRentalRequest::ReadPacket(BinaryReader *reader)
    {
        Name = reader->ReadString();
        Renting = reader->ReadBoolean();
    }

    void ItemRentalRequest::WritePacket(BinaryWriter *writer)
    {
        writer->Write(Name);
        writer->Write(Renting);
    }

    short ItemRentalFee::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::ItemRentalFee);
    }

    void ItemRentalFee::ReadPacket(BinaryReader *reader)
    {
        Amount = reader->ReadUInt32();
    }

    void ItemRentalFee::WritePacket(BinaryWriter *writer)
    {
        writer->Write(Amount);
    }

    short ItemRentalPeriod::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::ItemRentalPeriod);
    }

    void ItemRentalPeriod::ReadPacket(BinaryReader *reader)
    {
        Days = reader->ReadUInt32();
    }

    void ItemRentalPeriod::WritePacket(BinaryWriter *writer)
    {
        writer->Write(Days);
    }

    short DepositRentalItem::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::DepositRentalItem);
    }

    void DepositRentalItem::ReadPacket(BinaryReader *reader)
    {
        From = reader->ReadInt32();
        To = reader->ReadInt32();
        Success = reader->ReadBoolean();
    }

    void DepositRentalItem::WritePacket(BinaryWriter *writer)
    {
        writer->Write(From);
        writer->Write(To);
        writer->Write(Success);
    }

    short RetrieveRentalItem::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::RetrieveRentalItem);
    }

    void RetrieveRentalItem::ReadPacket(BinaryReader *reader)
    {
        From = reader->ReadInt32();
        To = reader->ReadInt32();
        Success = reader->ReadBoolean();
    }

    void RetrieveRentalItem::WritePacket(BinaryWriter *writer)
    {
        writer->Write(From);
        writer->Write(To);
        writer->Write(Success);
    }

    short UpdateRentalItem::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::UpdateRentalItem);
    }

    void UpdateRentalItem::ReadPacket(BinaryReader *reader)
    {
        HasData = reader->ReadBoolean();

        if (HasData)
        {
            LoanItem = new UserItem(reader);
        }
    }

    void UpdateRentalItem::WritePacket(BinaryWriter *writer)
    {
        writer->Write(LoanItem != nullptr);

        if (LoanItem != nullptr)
        {
            LoanItem->Save(writer);
        }
    }

    short CancelItemRental::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::CancelItemRental);
    }

    void CancelItemRental::ReadPacket(BinaryReader *reader)
    {
    }

    void CancelItemRental::WritePacket(BinaryWriter *writer)
    {
    }

    short ItemRentalLock::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::ItemRentalLock);
    }

    void ItemRentalLock::ReadPacket(BinaryReader *reader)
    {
        Success = reader->ReadBoolean();
        GoldLocked = reader->ReadBoolean();
        ItemLocked = reader->ReadBoolean();
    }

    void ItemRentalLock::WritePacket(BinaryWriter *writer)
    {
        writer->Write(Success);
        writer->Write(GoldLocked);
        writer->Write(ItemLocked);
    }

    short ItemRentalPartnerLock::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::ItemRentalPartnerLock);
    }

    void ItemRentalPartnerLock::ReadPacket(BinaryReader *reader)
    {
        GoldLocked = reader->ReadBoolean();
        ItemLocked = reader->ReadBoolean();
    }

    void ItemRentalPartnerLock::WritePacket(BinaryWriter *writer)
    {
        writer->Write(GoldLocked);
        writer->Write(ItemLocked);
    }

    short CanConfirmItemRental::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::CanConfirmItemRental);
    }

    void CanConfirmItemRental::ReadPacket(BinaryReader *reader)
    {
    }

    void CanConfirmItemRental::WritePacket(BinaryWriter *writer)
    {
    }

    short ConfirmItemRental::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::ConfirmItemRental);
    }

    void ConfirmItemRental::ReadPacket(BinaryReader *reader)
    {
    }

    void ConfirmItemRental::WritePacket(BinaryWriter *writer)
    {
    }

    short NewRecipeInfo::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::NewRecipeInfo);
    }

    void NewRecipeInfo::ReadPacket(BinaryReader *reader)
    {
        Info = new ClientRecipeInfo(reader);
    }

    void NewRecipeInfo::WritePacket(BinaryWriter *writer)
    {
        Info->Save(writer);
    }

    short CraftItem::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::CraftItem);
    }

    void CraftItem::ReadPacket(BinaryReader *reader)
    {
        Success = reader->ReadBoolean();
    }

    void CraftItem::WritePacket(BinaryWriter *writer)
    {
        writer->Write(Success);
    }

    short OpenBrowser::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::OpenBrowser);
    }

    void OpenBrowser::ReadPacket(BinaryReader *reader)
    {
        Url = reader->ReadString();
    }

    void OpenBrowser::WritePacket(BinaryWriter *writer)
    {
        writer->Write(Url);
    }

    short PlaySound::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::PlaySound);
    }

    void PlaySound::ReadPacket(BinaryReader *reader)
    {
        Sound = reader->ReadInt32();
    }

    void PlaySound::WritePacket(BinaryWriter *writer)
    {
        writer->Write(Sound);
    }

    short SetTimer::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::SetTimer);
    }

    void SetTimer::ReadPacket(BinaryReader *reader)
    {
        Key = reader->ReadString();
        Type = reader->ReadByte();
        Seconds = reader->ReadInt32();
    }

    void SetTimer::WritePacket(BinaryWriter *writer)
    {
        writer->Write(Key);
        writer->Write(Type);
        writer->Write(Seconds);
    }

    short ExpireTimer::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::ExpireTimer);
    }

    void ExpireTimer::ReadPacket(BinaryReader *reader)
    {
        Key = reader->ReadString();
    }

    void ExpireTimer::WritePacket(BinaryWriter *writer)
    {
        writer->Write(Key);
    }

    short UpdateNotice::getIndex() const
    {
        return static_cast<short>(ServerPacketIds::UpdateNotice);
    }

    void UpdateNotice::ReadPacket(BinaryReader *reader)
    {
        Notice = new Notice(reader);
    }

    void UpdateNotice::WritePacket(BinaryWriter *writer)
    {
        Notice->Save(writer);
    }
}
